专栏首页liulun自己动手写客户端UI库——事件机制(设计思路大放送)

自己动手写客户端UI库——事件机制(设计思路大放送)

上一篇文章中我们创建了一个Button控件,并把这个控件显示在界面上,

在这一篇文章中,我们将为这个控件增加一个事件和一个方法

一:怎么绑定事件的问题

在Winform中,我们对一个按钮绑定事件的方式如下(这是真正的事件)

然而,在WUI库中,为一个按钮绑定事件是这样的,(这不是一个事件,这只是调用了一个方法,给这个方法传递了一个i额委托)

问题: 为什么会有这样的差异呢?实在是无奈之举(也希望园友多提意见) 回答: 我们在给一个WUI按钮绑定事件的时候,这个按钮有可能已经呈现在界面上了;也有可能还没有呈现在界面上; 如果还没有呈现在界面上,那也倒简单,我只要在呈现的时候(也就是把html代码append到浏览器之前),顺便用js给他绑定一个click事件就好了。 但如果他已经呈现在界面上了,该怎么办呢?我虽然也可以用JS绑定事件,但我却不知道该什么时候执行这段JS,这一段代码“btn2.Click += btn2_Click;”是我的用户写的,我不知道他们会什么时候用这一段代码。 所以,无奈之下,只能用这种方法“btn.BindClickEvent(OnClick);”来让用户绑定事件,这样我就可以在BindClickEvent方法内执行那一段JS代码了,毕竟BindClickEvent这个方法是我写的,我可以随意的控制他,让他做我想做的事情

二:Button的BindClickEvent方法

第一:这个方法接收一个类型为Action<Button,EventArgs>类型的参数,Action其实就是一个委托,如果对这个东西不了解的朋友,可以看看我之前写的一篇文章《30分钟Linq教程》泛型委托那个小节第二:我们把这个参数存入了一个私有的List容器中,为什么这么做呢?一个按钮可以绑定多个Click事件,而且还要有先后顺序,所以按顺序存好,后面点击事件触发的时候,就可以直接遍历这个容器,按顺序执行这个容器中的委托就好了第三:Button实例IsRendered属性标致只着当前控件是否已经渲染在界面上了第四:我们每在界面上添加一个Button,就把这个Button的实例存在这个字典中。为以后使用这个按钮(比如说触发他的事件)打下基础第五:我们判断是不是第一次对这个Button的实例做Click事件的绑定,如果是,那么就做下面的工作,如果不是,就不必做了;也就是说不管我给这个按钮绑定多少个Click事件,下面的工作也只做一次第六:我们让浏览器执行了一段JS脚本,这段Js脚本执行过之后,事件才算绑定成功;这段脚本给Button的Dom元素绑定了一个click事件,这个事件调用了C#中的ButtonClick方法,并给这个方法传递了一个参数,这个参数就是Button的ID

三:RenderContext的ButtonClick方法

第一: 在本系列的第一篇文章中,我们介绍了C#是怎么和JS通讯的,这里就不多做介绍,只说2点: 1、JS要通过window.external调用C#里的方法 2、要把浏览器的ObjectForScripting设置给一个对象,这个对象必须是ComVisible的 第二: 所有的按钮,Dom元素的所有的click事件都会流入这个方法,这个方法是个路由器,把事件路由给用户的委托 第三: 我们根据按钮的ID,从字典(上一个小节有介绍)中拿出了按钮的实例,然后调用了实例方法Click,

四:Button类的Click方法

我们在这个方法中,遍历了所有绑定到Button实例上的“事件”,并且执行了这些事件。 遗留问题:这里没有太关注事件的执行顺序,以后会改进

五:PanelMain的AddChild方法

第一: 假设一个控件还没有渲染到界面上,那么是否允许开发人员对他绑定事件呢?当然是允许的!那么对于这一类使用方式,是在什么时候绑定事件的呢?就是在渲染的时候绑定的! 我们把控件添加到页面之后,马上就执行了这项工作,Button的ToJs方法就是在做这个工作,稍后介绍这个方法 第二: 只有当一个控件渲染到界面上之后,我们才会把它存入静态字典中,就是这行代码:RenderContext.ControlDic.Add(ctl.Id, ctl); 第三: 对于一个容器控件来说,他有一个Children集合,用来存储他自身的子控件,就是这行代码:this.Children.Add(ctl);

六:Button的ToJs方法

在这个方法中,我们把绑定事件的JS脚本得到,并反馈给调用者, 以后可能还会有其他的脚本,所以智力使用了StringBuilder

七:移除一个事件绑定

第一: 事件列表中应该存在待移除的事件 第二: 事件列表中就剩这么一个待移除的事件,并且,这个按钮已经渲染在界面上了;就执行js的解绑脚本 第三: 在事件列表中移除这个事件

八:移除所有事件绑定

第一: 当事件列表中存在事件记录 第二: 这个按钮已经被渲染在页面上,那么就执行JS解绑脚本 第三: 清空事件记录容器

修改记录

2015-1-22:

完成了文章的部分内容,修改了昨天写的代码

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 学习WPF——了解路由事件

    入门 我们先来看一个例子 前台代码: 后台代码: 点击按钮的运行效果 第一个弹出窗口 第二个弹出窗口: ...

    liulun
  • 学习WPF——元素绑定

    概念 从源对象提取一些信息,并用这些信息设置目标对象的属性 示例 image.png image.png 数据绑定表达式使用XAML的标记扩展(因此具有花括号)...

    liulun
  • CMMI三个过程域的流程及达到特定目标、共性目标的要求(RD需求管理过程,PI产品集成过程,TS技术解决方案)

    RD需求管理过程 image.png PI产品集成过程 image.png TS技术解决方案 image.png

    liulun
  • 02-老马jQuery教程-jQuery事件处理

    在DOM中DOM0级绑定事件的方式是直接给事件属性赋值,但是这样有个缺点就是每次指定的事件处理程序会把之前的覆盖掉。

    老马
  • jQuery 事件绑定 和 JavaScript 原生事件绑定

    jQuery 中提供了四种事件监听绑定方式,分别是 bind、live、delegate、on,

    柳醉梦声
  • 前端基础-jQuery简单事件绑定

    cwl_java
  • 02-老马jQuery教程-jQuery事件处理

    1. 绑简单事件 在DOM中DOM0级绑定事件的方式是直接给事件属性赋值,但是这样有个缺点就是每次指定的事件处理程序会把之前的覆盖掉。 jQuery简单绑定事件...

    老马
  • 动态添加的html元素绑定事件的方法

    在js中写好方法名对应的方法就可以了,如果绑定方法的元素太多,可以考虑使用方法二;

    蓓蕾心晴
  • 逻辑卷管理器LVM

    版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/gon...

    魏晓蕾
  • 2019-08-03 mac系统查看所有安装的jdk版本

    https://blog.csdn.net/sweatott/article/details/89953162

    Albert陈凯

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动