美好的一天
我对在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( “关于:空白”); 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动态更改其参数。可能吗?感谢您提前回答,最好的问候,
帕维尔
答案 0 :(得分:6)
我之前和WebControl一起工作过,就像你想从内存加载一个html但是有同样的问题,body是null。经过一些调查后,我注意到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;
}
WPF上需要DoEvents方法。对于System.Windows.Forms,可以使用Application.DoEvents()。
答案 1 :(得分:1)
另一种做同样事情的方法是:
webBrowser1.DocumentText = "<html><body>blabla<hr/>yadayada</body></html>";
这没有任何额外的初始化