我在项目中使用WebBrowser
控件来显示在运行时生成/操作的复杂HTML文档。
我注意到,通过创建HtmlElement
对象以编程方式从C#构造DOM比生成HTML字符串并将其传递给WebBrowser
慢约3倍,后者又会解析它以生成DOM 。在漫长的文档之间导航时,这两种方式都会产生明显的延迟。
我正在寻找在同一WebBrowser
控件中切换多个文档的最快方法,理想情况下无需为每个文档重复生成DOM树。是否可以在我的程序中的某处缓存HtmlElement
个对象树,然后根据需要将它们重新插入WebBrowser
?
答案 0 :(得分:2)
我将根据原生win32 COM API描述解决方案;在C#中编写互操作(或在pinvoke.net上找到它)应该不会太困难。或者,您可能需要使用托管对象公开的特性来获取本地特性。
您不太可能比IE的解析器更快地构建DOM,因此创建一个空白的HTMLDocument(在本机代码中为CoCreateInstance(CLSID_HTMLDocument))和QueryInterface()为其IMarkupServices实现的HTMLDocument。还使用IMarkupServices :: CreateMarkupPointer()方法创建两个IMarkupPointers。
接下来调用IMarkupServices :: ParseString()来解析你的HTML。这将为您提供指向包含DOM的IMarkupContainer的指针,以及指向DOM的开头和结尾的两个IMarkupPointer。现在,您可以使用IMarkupServices :: Move()将数据从一个IMarkupContainer移动到另一个IMarkupContainer。
因此,您将使用的一般方案是使用单个HTMLDocument,它是您的“显示”文档,它与IMarkupContainer(您可以只使用QueryInterface())相关联。然后你有一个向量或列表或所有非显示标记容器中的任何一个。然后,您只需为显示文档创建一个标记指针,调用IMarkupPointer :: MoveToContainer(displayDocumentContainer,true),然后使用它将显示容器中的内容移动到不显示容器,反之亦然。
有一点需要注意:您必须只能在创建它们的线程上访问这些对象,或者获取它们。所有IE对象都是STA对象。如果您需要多线程访问,则必须编组。
如果您有具体的跟进问题,请与我们联系。
参考文献:
答案 1 :(得分:2)
这样做
// On screen webbrowser control
webBrowserControl.Navigate("about:blank");
webBrowserControl.Document.Write("<div id=\"div1\">This will change</div>");
var elementToReplace = webBrowserControl.Document.GetElementById("div1");
var nodeToReplace = elementToReplace.DomElement as mshtml.IHTMLDOMNode;
// In memory webbrowser control to load fragement into
// It needs this base object as it is a COM control
var webBrowserFragement = new WebBrowser();
webBrowserFragement.Navigate("about:blank");
webBrowserFragement.Document.Write("<div id=\"div1\">Hello World!</div>");
var elementReplacement = webBrowserFragement.Document.GetElementById("div1");
var nodeReplacement = elementReplacement.DomElement as mshtml.IHTMLDOMNode;
// The magic happens here!
nodeToReplace.replaceNode(nodeReplacement);
答案 2 :(得分:1)
我真的需要了解更多关于如何生成这些文档的信息。将数据放入XML文档然后使用XSL转换将数据转换为HTML并将其传递给WebBrowser控件可能会更快。
.NET的XSLT实现的好处在于它需要XSL源并将其编译为临时程序集以加速转换。
如果您决定走这条路,请查看MVP.XML项目,该项目为库存XSLT实现添加了一些不错的exslt功能。
答案 3 :(得分:0)
也许不是缓存DOM,你只需在表单上的几个WebBrowser控件之间切换 - 只有活动的控件可见?
答案 4 :(得分:0)
你可以这样做吗?