最近從技術支持轉到開發崗,做Silverlight部分的開發,用的Prism+MVVM,框架由同事搭好,目前做的主要是功能實現,用到了一些東西,側重於如何使用,總結如下
1.UI控件與布局
常用的主要是Grid、StackPanel、Border,其中最常用的的是Grid,是一種行列組成的網格布局,特別是划分一個面板的區域時很方便,如圖所示,通過Grid.RowDefinitions將整個面板划分為兩大部分進行布局設計,而在局部澤運用了Grid.ColumnDefinition來進行列的划分,通過使用Grid能夠快速將一個面板進行網格划分,實現自己的頁面布局。


StackPanel則是一個允許對所屬內容進行水平或垂直排列的容器,Border這個的特點則在於可以添加邊框,如圖所示,通過BorderThickness和BorderBrush分別設置邊框的粗細和顏色,Grid.Column="3"指的是這個Border在網格中的位置為所屬網格的第四列,當然,網格中還可以嵌套網格,相當於一個網格中再進行網格划分。
目前偏向於使用Grid,一個容器里需要設置多項時就Grid里在嵌套Grid,因為使用最方便,設計起來容易,需要邊框的時候使用Border。
需要特別注意一點的是,設計界面的時候一定要考慮容器大小發現變化,比如用戶對窗口進行縮放,所以最好使用相對布局。
不建議指定Width、Height,最多使用"Magrin"來設置控件與父容器邊框的距離,多用“HorizontalAlignment”和“VerticalAlignment”來設置控件的位置,這樣窗口大小發生變化時布局才能統一協調。
另外有時還需要對UI控件的模板進行重寫,比如ListBox里放置TextBlock來顯示綁定的數據,對符號設置旋轉角度等等,這時就需要根據實際應用情況進行設置。


另外,項目中使用了第三方控件Telerik的RadControl For Silverlgiht系列,效果還不錯,而且基本為所有語言提供了精心制作的UI控件,地址http://docs.telerik.com/
2.MVVM
熟悉MVC了后對MVVM就能很快熟悉,關於MVC如果還陌生可以參考斯坦福公開課學習筆記1來幫助理解,也是為了將界面與邏輯分離,界面View即V還是直接在xaml中設計,ViewModel即VM邏輯實現則單獨寫在一個文件,是UI與邏輯的分離,數據傳遞則通過在xaml下的cs文件中使用DataContext與ViewModel這一層進行綁定來實現。


這中間遇到一個問題,如果MVVM模式下要求一個操作后關閉自身窗口如何實現?這不是與MVVM模式下UI與邏輯分離相違背嗎?
有三個方法,一是通過將V窗口傳到ViewModel里去,然后去控制關閉,這顯示違背了MVVM模式設計初衷,但是這里由於使用了第三方控件,在ViewModel中接收傳遞過來的窗口這個參數時,強制轉換遇到一些問題,故不用此法。
二是嚴格遵守MVVM模式來實現View與ViewModel進行交互,暫時未實現,感興趣參考這篇博文http://www.cnblogs.com/henryzhu/archive/2013/01/26/mvvm-viewmodel-view-interaction.html
三是直接將關閉窗口這個動作“this.close"傳遞進去,然后在ViewModel中觸發這個動作即可,這個簡單可行,暫時用此法。


3.數據綁定
需要改變UI上的顯示的數據,最直接的就是給UI控件設置標示符,寫代碼時根據標識符找到控件,更新數據即可。
但是在MVVM下,稍有些不同,需要進行綁定設置。



有幾個需要注意的是,
一是IValueConverter接口,當UI上有一項值是根據一個變量的返回值來確定,但是返回值是是int類型的數字或其他,但要求顯示的是文字,例如,返回值1代表“在審”,返回值為2則代表“未審”,可以通過IValueConverter這個轉換器接口實現,重寫Convert、ConvertBack兩個方法即可。詳細參考:http://www.silverlightchina.net/html/study/WPF/2012/0913/18875.html


二是INotifyPropertyChanged接口,如果某一項值改變了,如何通知UI也去更改呢,例如頁面上顯示根據不同條件查詢出來的異常數據數量AbnormalProjectCount,如何讓UI知道這個值改變了呢?通過繼承INotifyPropertyChanged接口即可。

4.await/async
.Net FrameWork4.5中新的關鍵字await/async,當使用await時,方法中需要聲明為async,作用是當執行到await的方法時,當前方法會掛起,直到await方法執行完畢返回值后再繼續執行。


5.Linq查詢
在上圖中有這樣一段代碼,使用的就是Linq查詢,根據Linq的介紹,使用LINQ可以查詢C#中許多不同的數據源,包括對象、SQL 數據庫、XML 文檔、實體數據模型和外部應用程序。

6.WCF RIA Services
Silverlight中如何與數據庫交互,實現增刪改查呢?答案是WCF RIA Services,但是有幾點需要注意:
(1)數據庫對應的表必須要有主鍵,否則設置時讀取不了實體類;
(2)實體模型的屬性設置中,Code Generation Strategy這一屬性設置為“Default”;
(3)刪除后綴為.tt的兩個文件;
(4)建立域服務DomainServices前注意先編譯一遍,不然無法讀取到更新的實體模型類。
詳細關於WCF RIA Services的使用以及設置注意事項參考MSDN的資料:
演練:創建 RIA Services 解決方案
http://msdn.microsoft.com/zh-cn/library/ee707376(v=vs.91).aspx
"Some Entity Framework context classes may have been excluded" message when adding a new Domain Service Class“
http://support.microsoft.com/kb/2745294
7.序列化
程序運行時,數據對象都保存在內存當中,當需要解析文件讀取數據或根據數據生成對象並保存成文件時,就需要進行序列化和反序列化,以XML文件為例。

8.委托與事件
應用場景:B窗口提交了數據,A窗口中數據列表需要自動更新,就可以通過委托與事件來實現,類似地,在地圖上框選一個范圍,自動讀取范圍值並顯示出來也可以通過委托與事件實現。

使用步驟是:
(1)定義委托與事件

(2)定義發布事件的類(調用它會觸發事件),在B窗口中提交數據后觸發事件。

(3)訂閱事件,以及處理事件的方法,在A窗口的構造函數中訂閱事件,這樣當B窗口提交數據后,A窗口訂閱到這個事件,知道數據更新了,重新獲取一次數據,數據列表就更新了。
類似於iOS中的delegate與Flex的消息機制。
