0

WebBrowser在我的项目中使用控件来显示在运行时生成/操作的复杂 HTML 文档。

我注意到,通过创建HtmlElement对象以编程方式从 C# 构造 DOM 比生成 HTML 字符串并将其传递给 DOM 慢约 3 倍WebBrowser,后者又解析它以生成 DOM。在冗长的文档之间导航时,这两种方式都会产生明显的延迟。

我正在寻找在同一WebBrowser控件中的多个文档之间切换的最快方法,理想情况下无需为每个文档重复生成 DOM 树。是否可以在我的程序中的某处缓存对象树HtmlElement,然后根据需要将它们重新插入WebBrowser

4

5 回答 5

2

我将根据本机 win32 COM API 来描述解决方案;在 C# 中编写互操作(或在 pinvoke.net 上找到)应该不会太难。或者,您可能需要使用托管对象公开的属性来获取本机对象。

您自己构建 DOM 的速度可能不会比 IE 的解析器快,因此创建一个空白 HTMLDocument(在本机代码中为 CoCreateInstance(CLSID_HTMLDocument))和 QueryInterface() 用于其 IMarkupServices 实现的 HTMLDocument。还使用 IMarkupServices::CreateMarkupPointer() 方法创建两个 IMarkupPointer。

接下来调用 IMarkupServices::ParseString() 来解析您的 HTML。这将为您提供一个指向包含您的 DOM 的 IMarkupContainer 的指针,以及指向您的 DOM 开头和结尾的两个 IMarkupPointer。现在您可以使用 IMarkupServices::Move() 将数据从一个 IMarkupContainer 移动到另一个。

因此,您将使用的一般方案是拥有一个 HTMLDocument,它是您的“显示”文档,并且它与 IMarkupContainer 相关联(您可以只使用 QueryInterface() )。然后你有一个向量或列表或所有非显示标记容器中的任何一个。然后,您只需为显示文档创建一个标记指针,调用 IMarkupPointer::MoveToContainer(displayDocumentContainer, true),然后使用它将内容从显示容器移动到不显示的容器,反之亦然。

需要注意的一件事:您只能在创建它们或获取它们的线程上访问这些对象。所有 IE 对象都是 STA 对象。如果需要多线程访问,则必须编组。

如果您有具体的后续问题,请告诉我。

参考:

于 2009-03-10T22:24:01.347 回答
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);
于 2009-03-13T00:52:06.640 回答
1

我真的需要更多地了解您如何生成这些文档。将数据转换为 XML 文档,然后使用 XSL 转换将数据转换为 HTML 并将其传递给 WebBrowser 控件可能会更快。

.NET 的 XSLT 实现的好处在于它采用 XSL 源并将其编译为临时程序集以加快转换速度。

如果您决定走这条路,请查看 MVP.XML 项目,该项目为现有的 XSLT 实现添加了一些不错的 exslt 功能。

于 2009-03-10T22:23:21.347 回答
0

也许您可以在表单上的几个 WebBrowser 控件之间切换而不是缓存 DOM - 只有活动的控件是可见的?

于 2009-02-25T16:24:08.590 回答
0

你能做这样的事情吗?

  • 创建要在 DIV 中显示的内容
  • 在不可见的 DIV 中创建辅助内容(在后台)
  • 通过玩可见性来交换内容
于 2009-03-10T22:25:46.147 回答