Построение деревьев объектов HtmlElement - PullRequest
4 голосов
/ 10 марта 2009

Я использую элемент управления MSIE WebBrowser в настольном приложении C # и ищу способ построения и поддержки деревьев объектов HtmlElement вне этого элемента управления. Я пытаюсь быстро переключаться между несколькими сложными страницами без дополнительных затрат на повторный анализ HTML каждый раз (и я не хочу поддерживать несколько элементов управления, которые отображаются / скрываются при необходимости). Я обнаружил, что а) я могу создавать HtmlElement объекты только через HtmlDocument элемента управления и б) как только я удаляю «ствол» из HtmlElement объектов из HtmlDocument элемента управления, он «умирает», даже если я продолжайте поддерживать сильную ссылку на корневой элемент. Как я могу это сделать?

P.S. Я готов рассмотреть альтернативные элементы управления браузером (например, Gecko), если они позволят мне выполнить вышеуказанное.

Ответы [ 4 ]

4 голосов
/ 13 марта 2009

Это сделает это

// 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 в памяти в других объектах?

2 голосов
/ 13 марта 2009

Вы можете использовать библиотеку MSHTML (mshtml.dll) для достижения этой цели. В основном вы должны использовать одну страницу about: blank, а затем динамически записывать и удалять содержимое с нее.

Смотрите это сообщение в блоге на эту тему

Вы также можете написать пользовательскую оболочку интерфейса, которая предоставляет необходимую функциональность из mshtml вместо ссылки на все это (почти 8 МБ), и это действительно легко сделать с помощью f12 в VS.

1 голос
/ 10 марта 2009

Вы действительно должны удалить их с энтузиазмом? Как насчет того, чтобы оставить свою «ветку» в DOM дочерней по отношению к DIV, чей стиль = «display: none». Таким образом, они настоящие, живые DOM-объекты, но не видимые.

0 голосов
/ 19 марта 2009

Я думаю, вы также можете использовать htmlagilitypack Он позволяет вам анализировать один раз, запрашивая дерево HTML с помощью XPath или итераторов и переписывая дерево с помощью метода save, когда закончите. В зависимости от вашей структуры, вы можете просто создать адаптер для классов, потому что он работает только для всего HTML-документа и вы хотите, чтобы он был только для элементов, но это не должно быть слишком сложно.

...