一、簡(jiǎn)單概念介紹
CAB提供一個(gè)開(kāi)發(fā)環(huán)境能很好的隱藏復雜度和提高生產(chǎn)力,通過(guò)高度抽象和關(guān)注點(diǎn)的分離,開(kāi)發(fā)人員能夠關(guān)注于業(yè)務(wù)邏輯提高基礎框架代碼的復用。Smart Part是整個(gè)CAB體系中重要的一部分,它可以將界面獨立于業(yè)務(wù)邏輯,讓界面和業(yè)務(wù)邏輯松散的耦合起來(lái)。Smart Part的應用中有幾個(gè)重要概念:
WorkSpace:作為一個(gè)容器,它可以統一的添加和顯示視圖。CAB中提供了一組控件作為視圖的容器,包括DeckWorkSpace,MDIWorkSpace,TabWorkSpace,WindowWorkSpace,ZoneWorkSpace。它們的作用有點(diǎn)類(lèi)似普通Windows 控件Panel,MDI窗口,TAB控件,Window窗體。在程序中根據名稱(chēng)可以通過(guò)WorkItem的WorkSpace集合索引到它們。
Smart Part: 也可以被稱(chēng)作View,實(shí)際上是一個(gè)個(gè)自定義的控件。
其他像WorkItem, State之類(lèi)的概念我在前兩次的學(xué)習筆記中曾經(jīng)介紹過(guò)了,這里就不再羅嗦了。
我們利用CAB中WorkSpace和Smart Part到底可以做些什么呢?WorkSpace可以一致的顯示多個(gè)控件,Shell 開(kāi)發(fā)人員創(chuàng )建定制的 workspaces 以提供控件周?chē)嗨频目蚣芎托揎?,共享的布局和定位,眩目的界面切換。下面我們還是通過(guò)一個(gè)實(shí)例來(lái)逐步理解CAB之Smart Part應用給我們帶來(lái)的好處,特別是在多個(gè)數據來(lái)源,將多個(gè)界面塊組合成一個(gè)統一美觀(guān)的整體時(shí)的應用方便性。
二、實(shí)例研究
1.應用場(chǎng)景
我相信研究過(guò)CAB的朋友肯定知道微軟提及的一個(gè)應用案例,Dell的客服桌面應用。該應用就是為了提高克服人員的辦公效率,將在提供客戶(hù)服務(wù)過(guò)程中需要從多個(gè)軟件系統獲取的信息,統一的集成到一個(gè)界面上來(lái)。也許大家會(huì )為該應用卓越的表現力,而感到親切、人性化,其實(shí)類(lèi)似這樣的應用我們通過(guò)CAB基礎件的應用,也可以達到類(lèi)似的效果,而不需要在界面化太多的精力去處理業(yè)務(wù)和界面之間的交互。為了能夠說(shuō)明問(wèn)題,我在學(xué)習過(guò)程中也做了一個(gè)簡(jiǎn)單的例子。
大家可能都開(kāi)發(fā)過(guò)網(wǎng)站或者用過(guò)Share point portal,那大家肯定都應該知道Web Part這個(gè)概念,在CAB中類(lèi)似的有了Smart Part的概念。Web Part能將一個(gè)個(gè)的信息塊集成到一個(gè)統一的Portal,Smart Part也能將不同的信息塊集成到一個(gè)界面。我們不妨假設這樣一個(gè)應用場(chǎng)景:
假設您是某百貨店的店長(cháng),希望每天能看到店里的銷(xiāo)售業(yè)績(jì),能看到自己每天的郵件,能看到自己喜歡的Blog上的資源,能有軟件提示自己每天的行程安排,最重要的是這些信息需要在一個(gè)統一的界面上顯示出來(lái)。面對這樣的需求,CAB來(lái)開(kāi)發(fā)界面大有用武之地,如果采用SOA的架構,更能使遺產(chǎn)系統的價(jià)值利用得更好。
2.需求分析
具體來(lái)說(shuō)該軟件有以下需求:
a.銷(xiāo)售業(yè)績(jì)的信息從店面現有的進(jìn)銷(xiāo)存系統中獲得。
b.Blog信息通過(guò)RSS獲得
c.每天的日程安排情況從秘書(shū)給自己設定的OA系統中獲得。
d.電子郵件通過(guò)集團統一的電子郵件系統中獲得,該郵件系統支持Web Service。
e.軟件界面簡(jiǎn)單統一,不能有過(guò)多的界面切換,最好能將所有概要信息顯示在一個(gè)界面之上。
f.軟件開(kāi)發(fā)周期要短,盡量利用現有系統的數據和邏輯。
g.界面可能會(huì )擴展,以后可能需要集成更多的系統。
面對這些需求,我們不難得出結論:用CAB基礎件開(kāi)發(fā)界面,用Web Service集成遺產(chǎn)系統信息都是不錯的選擇。
3.開(kāi)始建立應用
由于本例我們主要是為了學(xué)習CAB,至于Web Service的應用不做闡述。為了模擬類(lèi)似的效果,和SOA系統開(kāi)發(fā)過(guò)程中共享契約的原則,我們通過(guò)數據集來(lái)代表契約(XSD文件),用實(shí)際的XML文件代表Web Service的返回結果。
第一步:建立解決方案
a.啟動(dòng)VS2005,新建windows application,命名為T(mén)estSmartPart在項目中引用以下組件:
- Microsoft.Practices.CompositeUI;
- Microsoft.Practices.CompositeUI.WinForms;
- Microsoft.Practices.ObjectBuilder
第二步:繪制主窗口
a.將系統默認產(chǎn)生的Form1窗體,命名為T(mén)estSmartPartForm。
b.通過(guò)菜單-->工具-->自定義工具箱,選擇瀏覽Microsoft.Practices.CompositeUI.WinForms.dll,這是工具箱中能出現DeckWorkSpace,MDIWorkSpace等控件。
c.打開(kāi)TestSmartPartForm的設計視圖,調整窗體的高度和寬度,繪制5個(gè)DeckWorkSpace控件,分別命名為deckWS_Calendar,deckWS_Blogs,deckWS_Plan,deckWS_Task,deckWS_MainEmail。最終的界面效果如下圖:
第三步:定義數據實(shí)體(或者定義服務(wù)契約)
a.新建DataSources文件夾。
b.在DataSources文件夾中添加myBlogs,myEmail,myTasks,myPlans四個(gè)數據集。具體結構在文中不作描述,大家可以參考文后的源代碼。
c.根據數據集的結構,建立數據源。這里我們用Xml文件來(lái)代替數據庫中讀取的數據,分別添加myBlogs.xml,myEmail.xml,myTasks.xml,myPlans.xml。數據的內容我在此略過(guò)。將各個(gè)Xml文件內容錄入完成后,拷貝到運行目錄。我不知道為什么設置文件的Copy To OutPut Dierctory屬性為always,VS.Net編譯項目的時(shí)候無(wú)法復制到輸出目錄,難道該屬性是在建立安裝程序才起作用?后來(lái)我發(fā)現是生成的時(shí)候連同DataSource文件夾,一起輸出到了Bin目錄,因此讀取的時(shí)候也需要加上DataSource目錄。
第四步:建立視圖
a.建立BlogView、DailyPlan、DailyTask、Emails四個(gè)文件夾,這樣做的目的只是為了讓項目的結構更加清晰,同時(shí)以后要是對這些視圖進(jìn)行擴展,也可以把子視圖都放到對應的文件夾里。
b.在項目根目錄下添加UserControl,命名為T(mén)itlePart.cs。給該用戶(hù)控件加上一個(gè)lable控件,并且加入以下代碼:







































































c.建立BlogView視圖。在文件夾BlogView新建UserControl,命名為myBlogView.cs。將該類(lèi)從TitlePart繼承,將標題設置為“我的博客".加入Grid控件和數據集myBlogs進(jìn)行綁定。最終效果如下圖:
d.建立dailyPlanView視圖。在文件夾DailyPlan中新建用戶(hù)控件,命名為myPlan.cs。將該類(lèi)從TitlePart繼承,將標題設置為“我的日程"。加入Grid控件和數據myPlans進(jìn)行綁定。
e.建立myTaskView視圖。在文件夾DailyTask中新建一個(gè)UserControl,命名為myTask.cs,將該類(lèi)從TitlePart繼承,將標題設置為“銷(xiāo)售報表"。進(jìn)入myTask.cs的設計時(shí)加入控件reportView1,同時(shí)根據myTask數據集建立柱狀圖。最終界面如下圖:
f.建立EmailView視圖。為了表現WorkSpace能夠層層顯示子視圖,我們在EmailView視圖上,添加了兩個(gè)DeckworkSpace用來(lái)顯示郵件的列表視圖和詳細信息視圖。EmailView本身又是通過(guò)上一級WorkSpace顯示的。這里略去郵件列表視圖和郵件詳細信息視圖的建立過(guò)程,請參前面視圖建立過(guò)程和源代碼。
到此我們基本上完成各個(gè)視圖的建立,大家不難發(fā)現,他們之間是相對獨立的,和WorkSpace無(wú)關(guān)的。
第五步:編寫(xiě)WorkItem和Controller,連接所有視圖
a.建立應用入口類(lèi)。新建SmartPartApplication.cs,將類(lèi)代碼修改成以下形式:


































b.建立根級別的WorkItem。在本例中WorkItem的主要作用是提供顯示試圖的方法,將業(yè)務(wù)實(shí)體數據填充到數據集,并且讓數據集和控件綁定。
以顯示BlogView為例,我們來(lái)說(shuō)明WorkItem是如何將BlogView展示到特定的WorkSpace的。首先我們來(lái)看以下代碼:











































系統通過(guò)入口程序會(huì )自動(dòng)調用SmartRootWorkItem的Run方法,然后調用ShowBlogView方法來(lái)顯示Blog視圖。我們需要重點(diǎn)關(guān)注的是ShowBlogView本身。在顯示視圖之前我們需要為視圖中用到的數據,創(chuàng )建實(shí)例并且將其載入WorkItem的State列表,以便在視圖和Controller中共享使用。如代碼:


最后我們需要將視圖,在住窗體的deckWS_Blogs控件中顯示。在WorkItem中我們直接可以通過(guò)this.Workspace[]來(lái)索引住窗體上的Workspace,CAB已經(jīng)自動(dòng)將在設計時(shí)添加的Workspace控件添加到了Workspaces列表。索引導特定的Workspace后,我們需要將要顯示的試圖添加到WorkItem的Items集合,最后通過(guò)Workspace.Show(view)來(lái)顯示視圖。代碼如下:



其他視圖的添加方法類(lèi)似,我就不再做說(shuō)明。
c.正對根級別的WorkItem,建立對應的Controller。新建RootController.cs,將RootController類(lèi)從Controller繼承,加入以下代碼,將其與WorkItem關(guān)聯(lián)。














同時(shí)為了將業(yè)務(wù)實(shí)體和WorkItem、View結合起來(lái),我們將數據集通過(guò)State列表共享。如以下代碼:























RootController類(lèi)中當然還共享了其他如DailyPlan、DailyTask等業(yè)務(wù)數據,由于篇幅不再列出,在源代碼中可以查看。
第六步:修改視圖代碼,在視圖中顯示數據。
我們還是以BlogView為例來(lái)說(shuō)明,視圖是如何將數據顯示出來(lái)的,其他視圖都相似,請參考源代碼。在視圖中主要是通過(guò)私有變量和加有[State]修飾符的屬性和業(yè)務(wù)數據、Controller相關(guān)聯(lián)的。代碼如下:





























第七步:特殊處理,視圖的嵌套。
EmailView視圖和其他視圖有些不一樣,EmailView視圖有DeckWorkspace,在DeckWorkspace中還必須顯示兩個(gè)子視圖。這樣就使數據的共享,WorkItem的訪(fǎng)問(wèn)存在少許差異。我們不妨首先來(lái)看SamrtRootWorkItem中顯示EmailView的方法:


















我們發(fā)現TestSmartPart.Emails.EmailWorkItem被加入SamrtRootWorkItem的Items集合,deckWS_MainEmail這個(gè)Workspace也被加入SamrtRootWorkItem的Items集合。因此訪(fǎng)問(wèn)這些Workspace時(shí),必須通過(guò)WorkItem.Parent.Workspaces[ ]來(lái)訪(fǎng)問(wèn)。代碼如下:























第八步:運行程序
經(jīng)過(guò)一些修改后,我們可以運行我們的例程,大家看看下面這個(gè)界面是不是像一個(gè)Portal???

聯(lián)系客服