【背景】基于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事件监听实现的更多相关文章

  1. 如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间

    1.安装FF的Firebug组件:点击FF的Tools的Add-ons菜单,输入Firebug关键字,并选择合适的版本Install. 2.安装完毕后地址栏右边会出现一个小虫图标,右边还有一个下拉箭头 ...

  2. 引入jquery时,页面一直加载

    注意jquery的引用位置最好放在<head>下面.

  3. Ionic3新特性--页面懒加载2加载其他组件

    在第一节中,我们介绍了页面的懒加载方式,并进行了初步的分析,这里,我们将进一步介绍如何配合页面懒加载进行其他组件Component.Pipe.Directive等的模块化,和加载使用. 首先说明一点, ...

  4. 让多个Fragment 切换时不重新实例化、FragmentTabHost切换Fragment时避免UI重新加载

    http://www.tuicool.com/articles/FJ7VBb FragmentTabHost切换Fragment时避免UI重新加载 不过,初次实现时发现有个缺陷,每次FragmentT ...

  5. 基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)

    基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 个人技术博客:http://www.cnblogs.com/M ...

  6. Vue.js中用webpack合并打包多个组件并实现按需加载

    对于现在前端插件的频繁更新,所以多多少少要对组件化有点了解,下面这篇文章主要给大家介绍了在Vue.js中用webpack合并打包多个组件并实现按需加载的相关资料,需要的朋友可以参考下.   前言 随着 ...

  7. vue(组件、路由)懒加载

    const Login = resolve => require(['@/components/Login'], resolve) //就不用import了 Vue.use(Router) le ...

  8. Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静态文件的加载load static),自定义simple_tag和inclusion_tag

    Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静 ...

  9. 第34天学习打卡(GUI编程之组件和容器 frame panel 布局管理 事件监听 多个按钮共享一个事件 )

    GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1 简介 GUi的核心技术:Swing AWT 1.界面不美观 2.需要jre环境 为什么要学习GU ...

随机推荐

  1. 非负随机变量X满足:(1-F(x)) 在 (0,+∞)积分为= E[X]

    机器学习作业的第一题最后一问卡住了,要证明 非负随机变量X满足 1 - F(X) 在 (0,+∞)上的积分是E(X);  关键的地方是积分换序,看原来的答案真的很难理解,画个图一下就懂了,码个链接,便 ...

  2. LAMP 一键部署

    LAMP 一键部署 部署http #!/bin/bash ### global variables export lamp_repo=http://192.168.1.5/lamp/ export l ...

  3. 将数组转化为json字符串(不使用json_encode函数)

    将数组转化为json字符串(不使用json_encode函数) public function arrayToJson($arr,$jsonStr=''){ $jsonStr.='{'; foreac ...

  4. python3 包的发布

    发布流程大概如下 1. 首先需要有一个python包,就是一个文件夹,但是此文件夹下面有__init__.py文件,里面内容是 现在要发布包TestMsg,这就是一个python包.在同级目录下新建s ...

  5. Java Web 基础(一) 基于TCP的Socket网络编程

    一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...

  6. Ubuntu强制卸载VMware-player

    有时候安装了vmwar-player,想再安装vmware-workstation,却提示一些古怪的消息(现在忘记具体是什么了).只能先卸载再安装 首先你可以尝试常规卸载: sudo vmware-i ...

  7. Linux命令之---mv

    命令简介 mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files) 命令格式 mv [选项] 源文件或目录 目标文件或目录 命令参数 -b 若需覆盖文件,则覆 ...

  8. MySQL之索引(四)

    压缩索引 MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能.默认只压缩字符串,但通过参数设置也可以对整数做压缩. MyISAM压缩每个索引块的方 ...

  9. Spring进阶-怎样集成定时调度Quartz

    在一些项目里面比如进销存系统,对一些过期图片的定时清理或者库存不足发出预警提示,就需要用到定时调度技术. 每当经过一段时间,程序会自动执行,就是定时调度.如果要使用定时调度,则必须保证程序始终运行才行 ...

  10. 39、apk瘦身(转载)

    本文转自::Android开发中文站 » 关于APK瘦身值得分享的一些经验 从APK的文件结构说起 APK在安装和更新之前都需要经过网络将其下载到手机,如果APK越大消耗的流量就会越多,特别是对于使用 ...