C# 为什么 WebBrowser_DocumentCompleted() 触发两次?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2328835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:28:08  来源:igfitidea点击:

Why is WebBrowser_DocumentCompleted() firing twice?

c#.netnavigationbrowser

提问by Bibhas Debnath

Well, I'm using a simple webbrowser control to browse to a page, so I need to change the Text of the form while doing so. I'm using -

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

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

but using a breakpoint, i noticed that, this event is firing twice. I even tried _Navigated()event. it also fired twice. Resulting the title to "Webber - google.co.in - google.co.in"..

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

I also noticed that this event fired several times while loading msn.com.. I'm trying to change the text of the form only when the page has finished loading totally..

我还注意到此事件在加载 msn.com 时触发了几次.. 我试图仅在页面完全加载完成后才更改表单的文本..

Any remedy?

有什么补救办法吗?

采纳答案by Krassi

You can check the WebBrowser.ReadyState when the event is fired:

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

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

ReadyState will be set to Complete once the whole document is ready.

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

回答by i_am_jorf

It gets fired once per frame.

每帧触发一次。

回答by Kyle Rozendo

Every time a frame loads, the event is fired.

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

Also, before you even go there, the IsBusyproperty will only be Truewhilst the first frame has not loaded.

此外,在您去那里之前,该IsBusy属性只会True在第一帧尚未加载时生效。

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

  //The page is finished loading 
}

回答by u109919

How To Determine When a Page Is Done Loading in WebBrowser ControlDocumentCompletedis WinForms' wrapper of the DocumentComplete evert, however WebBrowserDocumentCompletedEventArgs hides the sender parameter so you cannot tell which frame is raising the event. Alternatively you can check WebBrowser.ReadyState.

如何确定页面何时完成 在 WebBrowser 控件中加载DocumentCompleted是 WinForms 对 DocumentComplete 事件的包装器,但是 WebBrowserDocumentCompletedEventArgs 隐藏了 sender 参数,因此您无法判断哪个框架引发了事件。或者,您可以检查WebBrowser.ReadyState.

回答by Jennifer Zouak

Actually, it doesn't always get fired. Haven't figured out why not. I have a timer and just check the ReadyState repeatedly for a few minutes. (Using embedded browser control).

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

回答by Fraga

I have the same problem, and the reason was because, by default when you add the control it generate designer code like this.

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

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

and if you change the url after calling

如果您在调用后更改 url

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

It will load two different pages: About:Blankand NewUrl.com

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

Just, remove the designer code... and you'll stop the "double" event.

只需删除设计器代码……您就会停止“双重”事件。

回答by Jacob

if (browser.ReadyState != WebBrowserReadyState.Complete)is recommended.

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

And when there are frames in the page,DocumentCompleted will be fired several times.And this is difficult to solve.Some ways like checking the urls are not accurate.

并且当页面有frame时,DocumentCompleted会被触发多次,这个问题很难解决,比如检查url这样的一些方法是不准确的。

BTW, why not using this:

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

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

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

Try to using a fixed prefix,problem may be solved easily.

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

回答by Rushi Sheth

Might be you are subscribing this event multiple times like in your some method when your navigating to URL everytime you subscribe to this event.

可能是您多次订阅此事件,就像在您每次订阅此事件时导航到 URL 时的某些方法中一样。

To solve this problem, move that line out of the method and put it somewhere else where it will only be called once per instance. In the constructor of the class perhaps... That should solve your problem .

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

回答by Ali ?AKIL

If firing twice is a problem then this should work:

如果发射两次是一个问题,那么这应该有效:

  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
    }