4

WebBrowser在 C# 桌面应用程序中使用 MSIE 控件,并且正在寻找一种方法来构建和维护HtmlElement此控件之外的对象树。我试图在多个复杂页面之间快速切换,而不会产生每次重新解析 HTML 的开销(而且我不想维护多个根据需要显示/隐藏的控件)。我发现a)我只能HtmlElement通过控件创建对象,b)一旦我从控件HtmlDocument中删除对象的“主干” ,它就会“消失”,即使我一直保持对根元素的强引用。我怎样才能做到这一点?HtmlElementHtmlDocument

PS 如果它们允许我完成上述操作,我愿意考虑替代浏览器控件(例如 Gecko)。

4

4 回答 4

4

这会做到的

// 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);

我怀疑这会提高性能,因为文本渲染器很快,如果您有一个带有隐藏 div 的大页面或在其他对象的内存中有多个 div,消耗的内存仍然相同?

于 2009-03-13T00:32:53.690 回答
2

您可以使用 MSHTML 库 (mshtml.dll) 来实现这一点。基本上你会使用一个 about:blank 页面,然后动态地写入和删除其中的内容。

请参阅有关此主题的博客文章

您还可以编写一个自定义界面包装器,从 mshtml 公开您需要的功能,而不是引用整个东西(近 8MB),并且在 VS 中使用 f12 非常容易。

于 2009-03-12T23:19:10.153 回答
1

你真的需要彻底删除它们吗?如何将 DOM 中的“分支”作为样式 =“display:none”的 DIV 的子级。这样它们是真实的、活动的 DOM 对象,但不可见。

于 2009-03-10T20:28:10.907 回答
0

我认为您也可以使用htmlagilitypack 它允许您解析一次,使用 XPath 或通过迭代器查询 HTML 树,并在完成后使用保存方法重新编写树。根据您的结构,您可能只是围绕类创建一个适配器,因为它仅适用于整个 html 文档并且您只希望它适用于元素,但这应该不会太难。

于 2009-03-19T05:16:30.280 回答