【问题标题】:Why is WebBrowser_DocumentCompleted() firing twice?为什么 WebBrowser_DocumentCompleted() 触发两次?
【发布时间】:2011-01-20 16:37:46
【问题描述】:

好吧,我正在使用一个简单的 webbrowser 控件来浏览页面,所以我需要在这样做的同时更改表单的文本。我正在使用 -

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
     this.Text += " - " + webBrowser1.Document.Domain;
}

但是使用断点,我注意到,这个事件触发了两次。我什至尝试过_Navigated() 事件。它也发射了两次。结果标题为"Webber - google.co.in - google.co.in" ..

我还注意到这个事件在加载 msn.com 时触发了好几次。我只是在页面完全加载完成后才尝试更改表单的文本。

有什么办法吗?

【问题讨论】:

    标签: c# .net navigation browser


    【解决方案1】:

    您可以在事件触发时检查 WebBrowser.ReadyState:

    if (browser.ReadyState != WebBrowserReadyState.Complete)
        return;
    

    整个文档准备就绪后,ReadyState 将设置为 Complete。

    【讨论】:

    • 它很可能会再次触发文件中的任何外部 javascript 链接
    【解决方案2】:

    每次加载帧时,都会触发该事件。

    另外,在你去那里之前,IsBusy 属性只会是True,而第一帧还没有加载。

    void BrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
      if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
        return; 
    
      //The page is finished loading 
    }
    

    【讨论】:

    • 我不敢问,但你把它与活动联系起来了吗?只是,文件毕竟完成了。
    • 谢谢!正是我需要的 - 无法弄清楚为什么有些页面完全呈现,而另一些只呈现部分。
    【解决方案3】:

    我有同样的问题,原因是,默认情况下,当您添加控件时,它会生成这样的设计器代码。

    this.webBrowser1.Url =  new System.Uri("", System.UriKind.Relative);
    

    如果您在调用后更改网址

    InitializeComponent();
    WebBrowser.Navigate("NewUrl.com");
    

    它将加载两个不同的页面:About:BlankNewUrl.com

    只需删除设计器代码...您将停止“双重”事件。

    【讨论】:

    • 我遇到了同样的问题,这个解决方法对我来说很好。我有点惊讶 Url 属性似乎以某种方式“入队”: DocumentCompleted 使用 e.Url == "about:blank" 触发,即使我将其挂钩 (+=) after a Url = "http://..." 声明
    【解决方案4】:

    每帧触发一次。

    【讨论】:

      【解决方案5】:

      如果触发两次是一个问题,那么这应该可以工作:

        string body="";
      
          private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
          {
              if (body == webBrowser1.Document.Body.InnerHtml) return;
              body = webBrowser1.Document.Body.InnerHtml;
      
              // Here is something you want
          }
      

      【讨论】:

      • 如果正文之间的内容这么多,时间就会这么长。
      【解决方案6】:

      当您每次订阅此事件时导航到 URL 时,您可能会多次订阅此事件,就像您使用某种方法一样。

      要解决此问题,请将那条线移出方法并将其放在其他地方,每个实例只会调用一次。也许在类的构造函数中......那应该可以解决你的问题。

      【讨论】:

        【解决方案7】:

        实际上,它并不总是被解雇。还没想明白为什么不行。我有一个计时器,只是反复检查 ReadyState 几分钟。 (使用嵌入式浏览器控件)。

        【讨论】:

          【解决方案8】:

          推荐if (browser.ReadyState != WebBrowserReadyState.Complete)

          而且当页面中有框架的时候,DocumentCompleted会被触发几次。这很难解决。有些方法比如检查url是不准确的。

          顺便说一句,为什么不使用这个:

          this.Text = stringA + " - " + webBrowser1.Document.Domain;

          尽量使用固定前缀,问题可能会很容易解决。

          【讨论】:

            【解决方案9】:

            How To Determine When a Page Is Done Loading in WebBrowser Control DocumentCompleted 是 WinForms 对 DocumentComplete evert 的包装,但是 WebBrowserDocumentCompletedEventArgs 隐藏了 sender 参数,因此您无法判断是哪个框架引发了事件。 或者您可以查看WebBrowser.ReadyState

            【讨论】:

              猜你喜欢
              • 2016-06-02
              • 1970-01-01
              • 2017-01-08
              • 1970-01-01
              • 2011-01-27
              • 2021-07-08
              • 1970-01-01
              • 1970-01-01
              • 2014-10-05
              相关资源
              最近更新 更多