skr*_*was 1 html c# browser dom
美好的一天
我有关于在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();
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
这次this.webbMain.DocumentText包含从文件中读取的Html数据,但doc.Body再次返回null,我仍然无法使用元素
getByElementId()方法.当然,当我有文本时,我会尝试正则表达式获取指定的字段,或者可能做其他技巧来实现目标,但我想知道 - 有没有简单的方法来主化html?对我来说,理想的方法是在内存中创建HTML文本,将其加载到WebBrowser控件中,然后使用ID动态更改其参数.可能吗?感谢您的回答,最好的问候,
帕维尔
我之前和WebControl一起工作过,就像你想从内存中加载一个html但是有同样的问题,body是null.经过一些调查后,我注意到Navigate和NavigateToString方法异步工作,因此控件加载文档需要一点时间,文档在调用Navigate后不可用.所以我做了类似的事情(wbChat是WebBrowser控件):
wbChat.NavigateToString("<html><body><div>first line</div></body><html>");
DoEvents();
Run Code Online (Sandbox Code Playgroud)
其中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);
}
Run Code Online (Sandbox Code Playgroud)
它对我有用,在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");
Run Code Online (Sandbox Code Playgroud)
我不知道这是不是这样做的正确方法,但它为我解决了问题,也许它对你有帮助.
后来编辑:
public object ExitFrame(object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}
Run Code Online (Sandbox Code Playgroud)
WPF上需要DoEvents方法.对于System.Windows.Forms,可以使用Application.DoEvents().