Построение деревьев объектов HtmlElement

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

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


person Tony the Pony    schedule 10.03.2009    source источник


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

person TFD    schedule 13.03.2009

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

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

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

person Fraser    schedule 12.03.2009

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

person jlew    schedule 10.03.2009
comment
К сожалению, отдельные страницы слишком сложны, чтобы их можно было поддерживать в DIV одной гигантской мастер-страницы... - person Tony the Pony; 10.03.2009
comment
Как насчет фреймов в наборе фреймов? - person jlew; 11.03.2009

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

person weismat    schedule 19.03.2009
comment
Могу ли я вставить сгенерированное дерево в элемент управления WebBrowser? В описании проекта говорится, что он не зависит от MSHTML, поэтому я предполагаю, что он использует классы, отличные от HtmlDocument/HtmlElement в System.Windows.Forms. - person Tony the Pony; 19.03.2009
comment
Конечно, используйте метод Save для HTMLDocument, чтобы сохранить его в потоке, и используйте свойство WebBroweser.DocumentStream, чтобы сгенерировать содержимое в контроль WebBrowser. - person weismat; 19.03.2009
comment
Но DocumentStream — это текст, так что я несу штраф за синтаксический анализ, которого я пытался избежать в первую очередь, не так ли? - person Tony the Pony; 19.03.2009
comment
Я думаю, вы бы разобрали один раз, поработали с деревом, а затем вернули дерево в самый конец только один раз. Таким образом, синтаксический анализ/адаптация будет происходить только один раз. - person weismat; 20.03.2009