重绘WebBrowser内容时是否触发了事件?

时间:2017-01-31 14:38:07

标签: c#

我正在使用WebBrowser控件,并且在某个时刻我更新元素的样式,例如:WebBrowser1.Document.GetElementById("elementId").Style = "color: red";

WebBrowser控件会自动重绘以反映更改的样式,但DocumentCompleted事件不会触发。 在这种情况下是否会发生事件?

1 个答案:

答案 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");
}