本身動手寫客戶端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:
完成了文章的部份內容,修改了昨天寫的代碼
相關文章
相關標籤/搜索