C# WebBrowser OnPropertyChange事件未触发

C# WebBrowser OnPropertyChange事件未触发,c#,html,winforms,webbrowser-control,propertychanged,C#,Html,Winforms,Webbrowser Control,Propertychanged,我有一个网页,上面有一个输入按钮。单击此按钮,在特定的div中加载一些数据。我的问题是我无法捕捉到这些数据 下面的代码是我试图解决这个问题,但没有成功 private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { HtmlElement div_result = webBrowser1.Document.GetElementById("div_resu

我有一个网页,上面有一个输入按钮。单击此按钮,在特定的div中加载一些数据。我的问题是我无法捕捉到这些数据

下面的代码是我试图解决这个问题,但没有成功

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    HtmlElement div_result = webBrowser1.Document.GetElementById("div_result");
    div_result.AttachEventHandler("onpropertychange", new EventHandler(resultEventHandler));
}
private void resultEventHandler(object sender, EventArgs e)
{
    MessageBox.Show("Loaded");
}
如果我点击输入按钮,div的内容会被修改,但是
resultEventHandler
不会触发

因此,我有两个问题:

  • 我的错在哪里
  • 使用C#中的
    WebBrowser
    控件使用ajax是否有一种“正常方式”(我的意思是不使用计时器或
    application.DoEvents()
    )呢
    更改子元素的innerText或innerHTML不会引发父元素的onpropertychange事件。

    我无法解释为什么HtmlElement事件不适用于您。但我也遇到了同样的问题,并通过使用COM包装解决了这个问题:

    mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document.DomDocument;
    mshtml.IHTMLElement2 div_result = (mshtml.IHTMLElement2)doc.getElementById("div_result");
    mshtml.HTMLElementEvents2_Event events = (mshtml.HTMLElementEvents2_Event)div_result;
    events.onpropertychange += resultEventHandler;
    

    这可能太晚了,但无论如何,如果您仍然想知道:

    1-HtmlElement div_result=webBrowser1.Document.GetElementById(“div_result”); 第#1行在网页已加载且浏览器已调用DocumentCompleted事件时执行。在事件处理程序中,首先检索指向DOM元素“div_result”的指针,然后分配一个名为div_result的HtmleElement类型变量

    2-div_result.AttachEventHandler(“onpropertychange”,新事件处理程序(resultEventHandler)); 第2行-注册“onpropertychange”事件,并将方法resultEventHandler指定为侦听器方法

    每次你点击网页上的按钮时,按钮(我假设)的形式会被提交,从而导致网页加载;顺便说一句,在单击按钮(获取或发布)时,您没有指定正在使用的发布方法。当网页下载完成并构建DOM元素树时,将调用DocumentCompleted事件。您将看到已完成的事件处理程序方法按照上述说明执行

    每次单击按钮时,都会重新加载网页,并为onpropertychange事件重新分配事件侦听器。您只分配事件侦听器。这项活动永远不会举行。每次单击按钮时,它都将被定义。你有一个典型的问题,先是鸡的问题,或是蛋的问题。但在您的例子中,您的check是按钮单击事件,导致DocumentCompleted方法运行,该方法重置方法中所有变量的状态,并且您的egg在单击网页上的按钮之前需要一个指向DIV元素的onpropertychange事件的指针。在从尚未构造的DOM获取指针之前,如何将事件侦听器分配给HtmleElement?在包含DocumentCompleted方法的类中放置一个布尔标志变量,并设置其初始状态。将div_result变量移到DocumentCompleted方法之外,以增加其作用域,并在按钮单击事件中保存其状态。这样,您将获得一个指向div元素的指针,并在第一次下载网页时设置其onpropertychange事件侦听器。如果只想将指向DIV元素的onpropertychange事件侦听器的指针设置一次(我在下面的示例代码中添加了一个),那么添加一个测试,下次单击按钮时,事件将触发。注意!确保在存储指向任何网页元素或其事件的指针后,不会向网页添加或删除任何元素。否则,您将不得不重新分析DOM,以获得指向元素在DOM树中的新位置的指针

    //见下文:

    class SomeClass
    {
        bool DocumentHasLoaded = false;
        HtmlElement div_result = null;
    
        //Constructor and other methods go here....
    
        //Then change your DocumentCompleted method to look like this:
        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
    
            if (DocumentHasLoaded == false)  // I prefer using a ! before the variable instead
            {
                DocumentHasLoaded = true;    // You will have to create your own appropriately timed mechanism to reset this variable's state should you want to execute the whole process again.
                div_result = webBrowser1.Document.GetElementById("div_result");
                div_result.AttachEventHandler("onpropertychange", new EventHandler(resultEventHandler));
            }
        }
    }
    

    为了回答你的第二个问题,我需要更多关于加载到DIV中的数据的信息;e、 g.它来自何处,是什么类型,以及您能想到的任何其他相关信息。

    我从msdn中阅读了此说明,但我没有子元素。我有一个非常特别的例子,是我为这个实验做的。这是因为“更改子元素的innerText或innerHTML不会导致父元素的onpropertychange事件触发。”?因为当内容更改时,DIV的属性不需要更改。“我更喜欢在变量之前使用!那么为什么还要做其他事情呢?”这是你的答案如果点击按钮导致页面刷新,那么这个分析是有意义的。但是,如果按钮点击从页面触发一些(客户端)javascript,其中JS改变了“div#u result”元素,那么onpropertychange的C#事件处理程序应该被触发,不是吗?FWIW我有一个类似的例子,C#事件处理程序过去被调用,但现在没有了。我目前怀疑由于Windows更新,MSIE中的行为发生了变化。看见