Reputation: 175
I'm using a WebBrowser control, and at a certain point I update the style of an element with, for instance: WebBrowser1.Document.GetElementById("elementId").Style = "color: red";
The WebBrowser control is automatically redrawn to reflect the changed style, but the DocumentCompleted event does not fire. Is there an event that fires in this case?
Upvotes: 0
Views: 717
Reputation: 14503
By default, the WinForms WebBrowser
control does not provide such an event.
But the control is really mighty, so with some tricks you can implement your desired behaviour: You already discovered, that you can access the DOM tree via the Document
property, but you can also communicate with scripts running in the WebBrowser via both the ObjectForScripting
property and the method Document.InvokeScript
. Since 'Vanilla' Javascript can listen to DOM tree changes, you can create a script, which registers for such changes and route them to the application that hosts your WebBrowser
control.
The small class below is just an example how this could work, of course you can alter the Javascript listener to receive more specialized events.
[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();
}
}
Just create an instance of this class with your WebBrowser as argument and you will be able to receive DOM tree changes via the DOMChanged
event:
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");
}
Upvotes: 2