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

上一篇文章中咱们建立了一个Button控件,并把这个控件显示在界面上,
在这一篇文章中,咱们将为这个控件增长一个事件和一个方法

一:怎么绑定事件的问题html

在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方法app

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

四:Button类的Click方法ui

咱们在这个方法中,遍历了全部绑定到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:
完成了文章的部份内容,修改了昨天写的代码
相关文章
相关标签/搜索