在
上一篇文章中我們創建了一個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:
完成了文章的部分內容,修改了昨天寫的代碼