引言
WebBrowser控件的DocumentCompleted事件一般就被认定为是在页面完全加载完毕后产生,而注释中也是这么写的:
但事实却并非如此。
首先它不一定会在完全加载完毕时才触发,有时就会在加载过程中就会触发。
其次按照“完全加载完毕后”来理解,会认为通常一次页面跳转只会引发一次该事件,事实也并非如此,某些页面加载时会引发十多次乃至更多。
试验
做一个简单试验,首先设计这样的界面:
然后为那个转到按钮添加单击事件处理:
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate(textBox1.Text);
}
再为WebBrowser控件的DocumentCompleted事件添加处理:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
listBox1.Items.Insert(0, webBrowser1.ReadyState);
}
在这里就是输出WebBrowser控件的ReadyState属性到列表中。
运行并测试:
可以看到加载某些页面时会引发很多次该事件,并且状态都是一连串的Interactive。
究其原因是与页面复杂度有关的,猜想是因iFrame或Ajax加载完毕而触发的。
而触发DocumentCompleted事件时ReadyState为Complete的情况通常只在每次加载页面时出现一次,所以这时我们才应认为其已完全加载。但也并非一个页面100%只会出现一次这种情况,比如页面中Google的“更多”链接点击后仅仅是弹出一个列表,但这时又会出现一次Complete。
这会导致什么问题?
假如在ReadyState为Interactive甚至是Loading时对页面实施操控,那很可能无效或引发异常。
而假如忽视这种一页多发事件的情况,会导致大量重复操作,从而引发异常或逻辑问题。
该如何解决?
以下代码可以确保你不会在未加载完毕时执行操作:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState < WebBrowserReadyState.Complete) return;
//执行正常流程代码…………
}
如果需要严格控制每页只能执行一次代码,那么需要附加一个属性或变量来记录上次访问的网址,并据此进行判断:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState < WebBrowserReadyState.Complete || webBrowser1.Url.ToString() == LastUrl) return;
LastUrl = webBrowser1.Url.ToString();
//执行正常流程代码…………
}
public string LastUrl
{
get
{
return _LastUrl;
}
set
{
_LastUrl = value;
}
}
private string _LastUrl;
结语
WebBrowser是非常实用的控件,但也可说是粗制滥造的典范,各种问题层出不穷,从注释对不上实际功能这一点来看,就知道开发者多么漫不经心了。还有就是ReadyState属性其实是一个非常关键的属性,而开发者却没有设置一个事件来监控其状态变更,真是太失败了。
更多相关经验请参看:WebBrowser控件使用技巧分享 在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件
转载请遵循此协议:署名 - 非商业用途 - 保持一致
并保留此链接:http://skyd.cnblogs.com/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述