我正在使用WebBrowser控件,并且在某个时刻我更新元素的样式,例如:WebBrowser1.Document.GetElementById("elementId").Style = "color: red";
WebBrowser控件会自动重绘以反映更改的样式,但DocumentCompleted事件不会触发。 在这种情况下是否会发生事件?
答案 0 :(得分:1)
默认情况下,WinForms WebBrowser
控件不提供此类事件。
但是控制真的很强大,所以通过一些技巧你可以实现你想要的行为:你已经发现,你可以通过Document
属性访问DOM树,但你也可以通过WebBrowser中的脚本进行通信ObjectForScripting
属性和方法Document.InvokeScript
。由于'Vanilla'Javascript可以监听DOM树的更改,因此您可以创建一个脚本,注册此类更改并将其路由到托管WebBrowser
控件的应用程序。
下面的小班只是一个如何工作的例子,当然你可以改变Javascript监听器来接收更多专业事件。
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[ComVisibleAttribute(true)]
public class DOMListener
{
public event Action DOMChanged;
private WebBrowser Browser;
public DOMListener(WebBrowser webbrowser)
{
this.Browser = webbrowser;
this.Browser.ObjectForScripting = this;
this.Browser.DocumentCompleted += OnDOMLoaded;
}
private void OnDOMLoaded(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlElement script = this.Browser.Document.CreateElement("script");
script.InnerHtml = "function listenToDOM() { document.addEventListener('DOMSubtreeModified', function(e) { window.external.DOMUpdate() }); }";
this.Browser.Document.GetElementsByTagName("body")[0].AppendChild(script);
this.Browser.Document.InvokeScript("listenToDOM");
}
public void DOMUpdate()
{
if (this.DOMChanged != null) this.DOMChanged.Invoke();
}
}
只需使用WebBrowser作为参数创建此类的实例,您就可以通过DOMChanged
事件接收DOM树更改:
private DOMListener Listener;
public Form1()
{
this.InitializeComponent();
this.Listener = new DOMListener(this.WebBrowser);
this.Listener.DOMChanged += this.OnDOMChanged;
this.WebBrowser.Navigate("www.google.de");
}
void OnDOMChanged()
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + ": DOM changed");
}