为什么WebBrowser_DocumentCompleted()会触发两次?

18

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

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

但是在使用断点时,我注意到该事件会触发两次。我甚至尝试了_Navigated()事件,它也会触发两次。导致标题变成了"Webber - google.co.in - google.co.in"

我还注意到,在加载msn.com时,该事件会多次触发。我想在页面完全加载完成后才更改表单的文本。

有什么解决方法吗?

9个回答

28

当事件被触发时,你可以检查WebBrowser.ReadyState属性:

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

当整个文档都准备好时,ReadyState 将被设置为 Complete。


1
很可能在文件中的任何外部JavaScript链接中再次触发。 - Starjumper Tech SL

18

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

此外,在您深入了解之前,IsBusy 属性仅在第一帧未加载时才为 True

void BrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
  if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
    return; 

  //The page is finished loading 
}

1
我害怕问,但你是否将其链接到事件? 它就是文档完成后的全部内容。 - Kyle Rosendo
谢谢!正是我所需要的 - 我找不出为什么有些页面完全呈现,而另一些页面只呈现部分。 - Elie

5

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

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

如果您在调用后更改了 URL

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

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

只需删除设计师代码...就可以停止“双重”事件。


我遇到了同样的问题,这个解决方法对我很有效。我有点惊讶Url属性似乎以某种方式被“排队”:即使我在Url =“http:// ...”声明之后挂钩(+ =),DocumentCompleted也会触发e.Url ==“about:blank”。 - Larry

3
如果连续触发两次是一个问题,那么这个方法应该管用:
  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
    }

如果正文内容很多的话,这将会花费很多时间。 - Gray Programmerz

3

它每帧只会被触发一次。


1
也许您多次订阅了此事件,例如在某些方法中每次导航到URL时都会订阅此事件。
为解决此问题,请将该行移出该方法并将其放置在其他地方,在每个实例中仅调用一次。可以将其放在类的构造函数中...这应该可以解决您的问题。

0

实际上,它并不总是被触发。还没有弄清楚为什么。我有一个计时器,只需重复检查几分钟的ReadyState即可。(使用嵌入式浏览器控件)。


0

如何确定WebBrowser控件加载页面完成 DocumentCompleted是WinForms对于DocumentComplete事件的封装,但是WebBrowserDocumentCompletedEventArgs隐藏了发送者参数,因此您无法确定哪个框架引发了该事件。 相反,您可以检查WebBrowser.ReadyState


0

如果 (browser.ReadyState != WebBrowserReadyState.Complete) 是推荐的。

当页面中有框架时,DocumentCompleted 会被触发多次。这很难解决。一些方法,如检查 URL,不太准确。

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

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

尝试使用一个固定前缀,问题可能很容易解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接