为啥 WebBrowser_DocumentCompleted() 触发两次?
Posted
技术标签:
【中文标题】为啥 WebBrowser_DocumentCompleted() 触发两次?【英文标题】: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 时触发了好几次。我只是在页面完全加载完成后才尝试更改表单的文本。
有什么办法吗?
【问题讨论】:
【参考方案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:Blank 和 NewUrl.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
。
【讨论】:
以上是关于为啥 WebBrowser_DocumentCompleted() 触发两次?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?