何謂CBS程序
CBS程序就是Client+Browser+Service的程序
純CS程序寫界面,有各種難處,那么我就在Client端引入Browser,讓Browser渲染基於HTML的UI界面
何謂WUI
就算用用HTML渲染UI界面,那么開發人員還是要掌握HTML+CSS+JS的知識,這些知識還是比較復雜的
WUI庫就是把
HTML+CSS+JS封裝成起來,組成一個界面元素庫,(類似於Extjs和easyui)
意圖是讓開發人員就只要掌握C#代碼,就能寫出漂亮的UI界面
第一步:WUI庫中的主窗口
一個WinForm程序必然有一個主窗口
我們把這個主窗口封裝到WUI庫中
|
![]() |
這個主窗口里面有一個WebBrowser,(這對於最終的用戶來說是不可見的,最終使用者不會操作這個WebBrowser)
|
![]() |
第二步:基礎的UI資源
我們在WUI庫中添加了一些基礎的UI資源,注意這些資源都會被復制到輸出目錄中,以后會考慮把這些內容做到Resource 中
|
![]() |
Index.html代碼中有兩點需要說明:
第一點:<meta http-equiv="X-UA-Compatible" content="IE=9" />
這是讓我們使用的WebBrowser,以IE9的模式來渲染界面,這一行代碼很重要,沒有這一行代碼,就算你裝了IE11,那么WebBrowser可能仍舊不會
表現成你想象的那樣;
第二點:window.external.WUIPageLoaded();
這行代碼會觸發WUI庫的內部事件,告訴最終用戶基礎的界面渲染已經完成了,用戶可以在這個事件觸發后,添加自己的界面元素。
這里涉及到JS和C#通訊,待會兒再說。
|
![]() |
第三步:CodeFirst創建UI
我們的WUI.Demo程序是一個WinForm程序集,但是我把IDE默認生成的那個窗口(Form1)刪掉了,而且修改了一下Program.cs程序
|
![]() |
在入口函數(Main)中,Application.Run了我們在WUI庫中創建的窗體(對於一個基於WUI庫創建的程序來說,只有這么一個窗口),我們知道這個窗口的WebBrowser中沒有任何東西,然而我們給WUIMain的屬性PanelMain賦值了,這就是我們要添加的東西了
|
![]() |
第四步:一個特殊的Panel
在上面的代碼中,我們給PanelMain屬性賦值為Main的實例,那么我們看一下Main是一個什么樣的類型 首先:這個類繼承自PanelMain類,PanelMain類是WUI庫提供的一個基類 其次:這個基類中有一個事件叫OnRender,剛剛我們看到的JS方法中window.external.WUIPageLoaded();這行代碼就會觸發這個事件。 |
![]() |
我們知道,一個用戶界面上,有很多界面元素,這些界面元素裝在一個容器中 我們的Main類型就是最上層的容器,最上層的容器是一個特殊的容器,他的類型是PanelMain;(你們可能看到了,我們在OnRender事件中又添加了一個Panel,這個Panel就不是特殊的容器了,但這篇文章我們不講這里) 到此為止,我們有一個疑問, 第一:什么時候觸發的OnRender事件呢? 這個時候我們就去看PanelMain的代碼 |
![]() |
看完PanelMain的代碼我們疑問更多了:
第一:什么時候調用的Loaded方法呢?
第二:什么時候執行的ToJs方法呢?
|
第五步:C#與JS通信的開端
我們知道,我們在Program.cs中把Main類的實例交給了WUIMain窗口,那么這個窗口拿Main類的實例做了什么呢?讓我們來看看WUIMain的代碼
|
![]() |
(說明一下WB就是我們的瀏覽器控件了) 首先:我們讓瀏覽器加載了那個主頁文檔(以后我們會做成動態的路徑) 第二:我們創建了一個RenderContext類的實例,並且把Main的實例交給類這個類型的構造函數 第三:我們把瀏覽器的DomWindow賦值給了這個實例的IHTMLWin屬性 第四:我們把這個實例賦值給了瀏覽器的ObjectForScripting屬性 |
這里有一點需要說明:要想使用IHTMLWindow2這個類型,必須要引用Mirosoft.mshtml這個擴展庫(注意,要在“擴展”里去找),引用了這個擴展庫之后,在名稱空間那里加上這一行using mshtml;就可以使用
IHTMLWindow2這個類型了
|
![]() |
第六步:C#與JS通信的高潮
然而我們的疑問還是沒有解決,那么只能繼續看RenderContext的代碼
首先:我們在這個類型的構造函數中得到了Main的實例
其次:我們把這個類型設置成了ComVisible
(注意,要想設置一個類型為ComVisible,必須要使用System.Runtime.InteropServices;名稱空間)
|
![]() |
大家注意到了,這個類型里有一個公開的WUIPageLoaded方法,這個方法名是不是很眼熟呢?對了,就是我們在JS中調用的方法window.external.WUIPageLoaded();
需要注意的有兩點:
第一:一定要用
window.external調用這個方法
第二:如果這個類型不設置成ComVisible就調用不到
第三:在WUIPageLoaded方法中,我們讓瀏覽器執行了一段腳本,就是PanelMain的ToJs方法里的腳本了,這個時候就把這個控件渲染到瀏覽器中去了
第四:我們調用了PanelMain實例的Loaded方法,在那個方法里,我們觸發了OnRender事件,這樣我們的用戶就知道什么時候他該接管接下去的工作了
|
注意:
在這里我們用C#讓瀏覽器執行了腳本
瀏覽器用JS代碼讓我們的C#也做了工作
這就是C#和JS的通信了呢!
|
第七步:尾聲
我們的程序看起來像這個樣子
我當然知道這不是你想要看到的結果
那么,請您對這篇文章點個贊吧------------------------->>
您的支持是我寫下一篇的動力!!!
|
![]() |
修改記錄
2015-1-19:
完成全部內容