【问题标题】:How to feed WebBrowser control and manipulate the HTML document?如何提供 WebBrowser 控件和操作 HTML 文档?
【发布时间】:2017-04-09 23:49:51
【问题描述】:

美好的一天

我对在 Windows 窗体应用程序中显示 html 文档有疑问。我正在开发的应用程序应该显示来自

的信息

html 格式的数据库。我将尝试描述我已经采取的行动(以及失败的行动):

1) 我尝试加载仅存在于内存中的“虚拟”html 页面并动态更改其参数(webbMain 是一个 WebBrowser 控件):

public static string CreateBookHtml()
{
 StringBuilder sb = new StringBuilder();

 //Declaration
 sb.AppendLine(@"<?xml version=""1.0"" encoding=""utf-8""?>");
 sb.AppendLine(@"<?xml-stylesheet type=""text/css"" href=""style.css""?>");
 sb.AppendLine(@"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.1//EN"" 
                    ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"">");
 sb.AppendLine(@"<html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"">"); 

 //Head
 sb.AppendLine(@"<head>");
 sb.AppendLine(@"<title>Exemplary document</title>");
 sb.AppendLine(@"<meta http-equiv=""Content-Type"" content=""application/xhtml+xml; 
                                                                charset=utf-8""/   >");
 sb.AppendLine(@"</head>");

 //Body
 sb.AppendLine(@"<body>");
 sb.AppendLine(@"<p id=""paragraph"">Example.</p>");
 sb.AppendLine(@"</body>");
 sb.AppendLine(@"</html>");

 return sb.ToString();
}

void LoadBrowser() { this.webbMain.Navigate("about:blank"); this.webbMain.DocumentText = CreateBookHtml(); HtmlDocument doc = this.webbMain.Document; }

这失败了,因为 doc.Body 为 null,并且 doc.getElementById("paragraph") 也返回 null。所以我不能更改段落 InnerText 属性。

此外,this.webbMain.DocumentText 是“\0”...

2) 我尝试在指定文件夹中创建 html 文件,将其加载到 WebBrowser,然后更改其参数。 Html 和

创建的一样

CreateBookHtml() 方法:

private void LoadBrowser()
        {
            this.webbMain.Navigate("HTML\\BookPage.html"));             
            HtmlDocument doc = this.webbMain.Document;
        }

这次this.webbMain.DocumentText包含从文件中读取的Html数据,但是doc.Body又返回了null,我还是不能使用元素

getByElementId() 方法。当然,当我有文本时,我会尝试使用正则表达式来获取指定的字段,或者可能会使用其他技巧来实现目标,但我想知道 - 是否有简单的方法来维护 html?对我来说,理想的方法是在内存中创建 HTML 文本,将其加载到 WebBrowser 控件中,然后使用 ID 动态更改其参数。可能吗?感谢您提前回答,最好的问候,

帕维尔

【问题讨论】:

  • WebBrowser控件没有NavigateToString方法

标签: c# html browser dom


【解决方案1】:

我前段时间使用过 WebControl,就像您想从内存中加载 html 但遇到同样的问题,body 为空。经过一番调查,我注意到 Navigate 和 NavigateToString 方法是异步工作的,因此控件加载文档需要一点时间,在调用 Navigate 后文档不可用。所以我做了类似的事情(wbChat 是 WebBrowser 控件):

wbChat.NavigateToString("<html><body><div>first line</div></body><html>");

DoEvents();

DoEvents() 的实现方式为:

[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public void DoEvents()
{
    DispatcherFrame frame = new DispatcherFrame();
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new DispatcherOperationCallback(ExitFrame), frame);
    Dispatcher.PushFrame(frame);
}

它对我有用,在 DoEvents 调用之后,我可以获得一个非空的主体:

mshtml.IHTMLDocument2 doc2 = (mshtml.IHTMLDocument2)wbChat.Document;

mshtml.HTMLDivElement div = (mshtml.HTMLDivElement)doc2.createElement("div");
div.innerHTML = "some text";
mshtml.HTMLBodyClass body = (mshtml.HTMLBodyClass)doc2.body;

if (body != null)
{
    body.appendChild((mshtml.IHTMLDOMNode)div);

    body.scrollTop = body.scrollHeight;
}
else
    Console.WriteLine("body is still null");

我不知道这是否是正确的方法,但它为我解决了问题,也许它也可以帮助你。

稍后编辑:

public object ExitFrame(object f)
{
    ((DispatcherFrame)f).Continue = false;
    return null;
}

DoEvents 方法在 WPF 上是必需的。对于 System.Windows.Forms,可以使用 Application.DoEvents()。

【讨论】:

  • 您好!谢谢你的回答。我想给它加点东西。首先,应该有 ExitFrame 方法体。它看起来像:ExitFrame(object f){((DispatcherFrame)f).Continue = false;return null;}。其次,我们必须在解决方案中添加两个程序集:WindowsBase.dll 和 Microsoft.mshtml.dll。第三:我在 WebBrowser 中找不到 NavigateToString 方法。最重要的是,您的解决方案有效(看起来很糟糕,但有效:)),我在上面写的只是为了其他读者。非常感谢!
  • 我忘记添加 ExitFrame 方法并提及程序集,我将编辑答案,以便代码更加可见。关于 NavigateToString - 我实际上使用的是 WebBrowser 控件的 WPF 版本,它实际上具有此方法(msdn.microsoft.com/en-us/library/…),虽然这很奇怪,因为我怀疑它是本机控件的包装器,就像 System.Windows 中的 WebBrowser 。形式。我对它的外观也不满意,但有时你只是无所事事......
  • 只是附带说明 HTMLBodyClass 可能会给 .net 版本 > 4 带来编译错误,而不是使用接口声明 HTMLBody。
【解决方案2】:

做同样事情的另一种方法是:

webBrowser1.DocumentText = "<html><body>blabla<hr/>yadayada</body></html>";

这无需任何额外的初始化即可工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多