【winform】基于UserControl实现webBrower组件时html页面元素加载及onclick事件监听实现
【背景】基于System.Windows.Forms.UserControl实现的webBrower组件在html内使用window.external调用winform事件失败。
【解决思路】借助winform的HtmlElementEventHandler完成html 页面元素点击时winform执行相应方法。
HTML
<input type="button" id="searchBtn" onclick="searchResource()">
<div id="resouceDetails" ></div>
<input type="hidden" id="isLoading" data-val="Y">
JS
function searchResource(){
1、$("#isLoading").val("N").attr("data-val","N");
2、使用ajax向后台请求数据并拼接内容至resourceDetails
$.ajax({
type : "post",
url : 略l,
data:略,
dataType : "json",
success: function(data) {
var htmlStr="";
if(data.length>0){
for(var i=0,len=data.length;i<len;i++){
htmlStr+="<div data-class=\"rDetails\" data-id=\""+data[i].id+"\">";
htmlStr+="<img ;
htmlStr+="</div>";
}
}
$("#resouceDetails").empty().append(htmlStr);
}
});
3、$("#isLoading").val("N").attr("data-val","Y");
}
C#
winform监听searchBtn(搜索按钮)的onclick事件,并在searchResource()方法执行完毕后监听 div[data-class='rDetails']的点击事件并执行后续winform事件。
实现思路:
1、页面加载完毕后绑定searchBtn(搜索按钮)的onclick事件监听。
2、因winform无法判断js方法何时执行完毕,在searchResource()方法内借助隐藏域、在winform内启用Timer,Timer.Tick事件执行时判断:js是否执行完毕(隐藏域的 data-val==Y时js执行完毕)。
3、借助HtmlElement、HtmlElementCollection完成div[data-class='rDetails']的点击事件监听注册。
private Timer timer1 =null;
public StudyResourceUCNew(){
InitializeComponent();this.webBrowser1.Navigate(LoadDataPath.loadResourceCenter());
this.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
}
/// <summary>
/// 网页加载完成的后续处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlDocument htmlDoc = webBrowser1.Document;
HtmlElement searchFrom=htmlDoc.All["searchForm"];
if(searchFrom!=null){
searchFrom.Click += new HtmlElementEventHandler(searchFrom_Click);
}
}
/// <summary>
/// 监听搜索按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void searchFrom_Click(object sender, EventArgs e)
{
timer1 = new Timer();
timer1.Interval = ;
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1EventProcessor);//添加事件
} public void timer1EventProcessor(object sender, EventArgs e)
{
HtmlDocument htmlDoc = webBrowser1.Document;
HtmlElement isLoading = htmlDoc.All["isLoading"]; //js拼接页面是否完成
if (isLoading.GetAttribute("data-val") == "Y") {
timer1.Stop();
timer1.Tick -= new EventHandler(timer1EventProcessor);
timer1 = null; //重新绑定资源的onclick事件
HtmlElement resouceDetails = htmlDoc.All["resouceDetails"];
HtmlElementCollection cells = resouceDetails.GetElementsByTagName("div");
for (var i = ; i < cells.Count; i++) {
var status = cells[i].GetAttribute("data-class");
if (status == "rDetails")
{
cells[i].Click += new HtmlElementEventHandler(showResourceDetial);
}
}
}
} /// <summary>
/// 查看资源详情
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void showResourceDetial(object sender, EventArgs e)
{
//do something
}
【问题】页面初次加载时需要执行searchResource()加载数据显示初始页面,js 执行searchResource()方法使用并不能触发HtmlElementEventHandler 监听。
代码调整:
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlDocument htmlDoc = webBrowser1.Document;
HtmlElement searchFrom=htmlDoc.All["searchForm"];
if(searchFrom!=null){
searchFrom.Click += new HtmlElementEventHandler(searchFrom_Click);
//js执行的searchForm click事件无法被监听到,需手动启动事件绑定线程
timer1 = new Timer();
timer1.Interval = 100;
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1EventProcessor);//添加事件
}
}
至此所有问题解决。
[ComVisibleAttribute(true)] public partial class StudyResourceUCNew : UserControl {
private Timer timer1 =null;
public StudyResourceUCNew() { InitializeComponent(); this.webBrowser1.Location=new Point(0,0); this.webBrowser1.Width = this.scrollPanel.Width; this.webBrowser1.Height = this.scrollPanel.Width; this.webBrowser1.Navigate(LoadDataPath.loadResourceCenter()); this.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted); }
/// <summary> /// 网页加载完成的后续处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { HtmlDocument htmlDoc = webBrowser1.Document; HtmlElement searchFrom=htmlDoc.All["searchForm"]; if(searchFrom!=null){ searchFrom.Click += new HtmlElementEventHandler(searchFrom_Click); //js执行的searchForm click事件无法被监听到,需手动启动事件绑定线程 timer1 = new Timer(); timer1.Interval = 100; timer1.Enabled = true; timer1.Tick += new EventHandler(timer1EventProcessor);//添加事件 } }
/// <summary> /// 监听搜索按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void searchFrom_Click(object sender, EventArgs e) { timer1 = new Timer(); timer1.Interval = 100; timer1.Enabled = true; timer1.Tick += new EventHandler(timer1EventProcessor);//添加事件 }
public void timer1EventProcessor(object sender, EventArgs e) { HtmlDocument htmlDoc = webBrowser1.Document; HtmlElement isLoading = htmlDoc.All["isLoading"];
//js拼接页面是否完成 if (isLoading.GetAttribute("data-val") == "Y") { timer1.Stop(); timer1.Tick -= new EventHandler(timer1EventProcessor); timer1 = null;
//重新绑定资源的onclick事件 HtmlElement resouceDetails = htmlDoc.All["resouceDetails"]; HtmlElementCollection cells = resouceDetails.GetElementsByTagName("div"); for (var i = 0; i < cells.Count; i++) { var status = cells[i].GetAttribute("data-class"); if (status == "rDetails") { cells[i].Click += new HtmlElementEventHandler(showResourceDetial); } }
}
}
/// <summary> /// 查看资源详情 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void showResourceDetial(object sender, EventArgs e) { StudyReSourceForm fm = new StudyReSourceForm(); HtmlElement cell = (HtmlElement)sender; fm.CurClickResourceID = int.Parse(cell.GetAttribute("data-id")); MyShowDialog.MyShowDialogFunc2(fm, this.FindForm()); } }
【winform】基于UserControl实现webBrower组件时html页面元素加载及onclick事件监听实现的更多相关文章
- 如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间
1.安装FF的Firebug组件:点击FF的Tools的Add-ons菜单,输入Firebug关键字,并选择合适的版本Install. 2.安装完毕后地址栏右边会出现一个小虫图标,右边还有一个下拉箭头 ...
- 引入jquery时,页面一直加载
注意jquery的引用位置最好放在<head>下面.
- Ionic3新特性--页面懒加载2加载其他组件
在第一节中,我们介绍了页面的懒加载方式,并进行了初步的分析,这里,我们将进一步介绍如何配合页面懒加载进行其他组件Component.Pipe.Directive等的模块化,和加载使用. 首先说明一点, ...
- 让多个Fragment 切换时不重新实例化、FragmentTabHost切换Fragment时避免UI重新加载
http://www.tuicool.com/articles/FJ7VBb FragmentTabHost切换Fragment时避免UI重新加载 不过,初次实现时发现有个缺陷,每次FragmentT ...
- 基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)
基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 个人技术博客:http://www.cnblogs.com/M ...
- Vue.js中用webpack合并打包多个组件并实现按需加载
对于现在前端插件的频繁更新,所以多多少少要对组件化有点了解,下面这篇文章主要给大家介绍了在Vue.js中用webpack合并打包多个组件并实现按需加载的相关资料,需要的朋友可以参考下. 前言 随着 ...
- vue(组件、路由)懒加载
const Login = resolve => require(['@/components/Login'], resolve) //就不用import了 Vue.use(Router) le ...
- Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静态文件的加载load static),自定义simple_tag和inclusion_tag
Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静 ...
- 第34天学习打卡(GUI编程之组件和容器 frame panel 布局管理 事件监听 多个按钮共享一个事件 )
GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1 简介 GUi的核心技术:Swing AWT 1.界面不美观 2.需要jre环境 为什么要学习GU ...
随机推荐
- Python 文件读写 文件和路径
1.在Windows上,使用倒斜杆作为文件夹之间的分隔符,在Linux上,使用正斜杠作为路径分隔符.在编写Python脚本时,可以os.path.join()函数来处理 在Windows环境下命令如下 ...
- JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线
455. [NOIP2017提高A组冲刺11.6]拆网线 (File IO): input:tree.in output:tree.out Time Limits: 1000 ms Memory L ...
- Cube HDU - 1220(思维)
Cowl is good at solving math problems. One day a friend asked him such a question: You are given a c ...
- Codeforces Round #464 (Div. 2) D. Love Rescue
D. Love Rescue time limit per test2 seconds memory limit per test256 megabytes Problem Description V ...
- [Hdu3652]B-number(数位DP)
Description 题目大意:求小于n是13的倍数且含有'13'的数的个数. (1 <= n <= 1000000000) Solution 数位DP,题目需要包含13,且被13整除, ...
- java中如何判断一个字符串是否包含另外一个字符串的方法
indexOf(String s)的使用,如果包含,返回的值是包含该子字符串在父类字符串中起始位置: 如果不包含必定全部返回值为-1 package my_automation; public cla ...
- Java面向对象---方法的创建与重载
方法的创建 方法就是可重复调用的代码段. 定义: 访问修饰符 返回值类型 方法名(参数){ 方法主体 } 返回值类型:void(无返回值):基本数据类型:应用数据类型:类对象等. 方法名的命名规则:第 ...
- java以正确的方式停止线程
java线程停止可以说是非常有讲究的,看起来非常简单,但是也要做好一些防范措施,一般停止一个线程可以使用Thread.stop();来实现,但是最好不要用,因为他是不安全的. 大多数停止线程使用Thr ...
- 将FragmentManger事务添加到返回栈中
FragmentManger事务添加或替换的 Fragment 后,这时点击 Back 键,程序并不会返回添加之前的状态. 我们可以使用 Transaction 对象的 addToBackStack( ...
- C# Params的应用
为了将方法声明为可以接受可变数量参数的方法,我们可以使用params关键字来声明数组,如下所示: public static Int32Add(params Int32[] values) { Int ...