代碼下載:
http://www.n-pei.com/download/SLVM_Product.zip
part1: 如何使用 RIA Services
part2: RIA Services更新和驗證
part3: RIA Services數據新增
part4: 皮膚的更改
part5: 報表的展示
part6:Endpoint的設置
part7:如何使用RIA Service Class Library
part8:url重寫和界面友好
part9:MVVM+RIA Service
週末就是爽,可以寫很多自己喜歡的代碼。。
今天花了 6 個小時去試着把第二篇 MVVm+RIA service 的例子寫出來。代碼寫的我都有點暈了,特別是頁面的 style 我發現比我後臺寫代碼還要花更多時間,看出來我是不會 blend 了,也不是搞設計的。
MVVM 模式中使用 RIA Service 提供數據 , 說白了 Model 部分其實已經差不多自動生成很多了。你可以再加以改造就可以了,不需要花很大力氣去寫那麼多 model 了。
這裏我使用一個數據庫表中的 Product 爲例子來實現增刪改查功能。我先聲明這篇文章描述的不是純粹的 MVVM 模式,因爲未使用 ICommand 。因爲對 ICmmand 不是很熟悉,我準備下一篇 MVVm 中再去使用它,供大家學習。
頁面的佈局如下:
如果你有興趣研究這個我一會把代碼上傳供你們下載。
先說說如何來實現的吧。
1. 創建 Business Application 模板。
2. 創建 Domain Service 。
3. 輔助類和資源的編寫
4. Model 部分的完成
5. ViewModel 部分的功能
6. View 界面的完成
7. 綁定數據 :
1. 創建 Business Application 模板:
這個就不用說了,你可以使用其它的模板,只要選上 RIA Service 就行了。
2. 創建 Domain Service :
我選用的表名字叫 Product :
創建好這個 ADO.NET Data Model 後,按步驟創建 Domain Service 。需要注意的是在 Domain Service 自動生成後需要添加一個查詢方法:
通過 productID 來查詢到需要的 product.
3. 輔助類和資源文件的編寫:
輔助的類主要是兩個轉換時間和貨幣單位的:
這個是時間格式的轉換,你也可以不使用它,它的使用時在數據綁定時在 blinding: field,Converter= 這種方式使用。具體的使用輕參看代碼。
因爲不像直接把 DomainContext 拖到 xaml 頁面中那樣子方便,所以很多驗證都需要在 Model 裏來搞定。你可以使用 try catch 來警告,或者是使用 Tooltip, 我這裏是使用了自定義的方法來驗證。比如我某個字段爲空時我點擊保存:
所有的警告信息我都是用 Resource 文件管理,這樣以後容易修改。
4. Model 部分的完成:
在 MVVM 中 Model 的作用就是能夠爲 View 提供數據,至於一些其他功能等操作都交給 ViewModel 部分處理。
這裏我們因爲是使用 RIA Service ,所以一定記得把如下兩個 namespace 加進來:
Model 部分的代碼比較多 , 我這裏就只給大家貼個類結構圖:
前面的兩個事件委託類都用來處理錯誤出現時和當數據交換完成事件發生時執行的動作。
ProductModel 類其實已經不是個純粹的 Model 類,它裏面有很多和 RIA Service 的數據交互處理。也算是準備數據。 Product 是個 Enumerator 他纔是最終要提供數據的實體。
這裏需要注意 Delete product 時,因爲 Domain Context 提供的方法中 remove() 返回結果是 void ,而我們需要讓 delete 事件發生時返回一個 bool 類型來確定是否記錄刪除成功,所以方法如下:
5. ViewModel 部分的功能
Base 類是個抽象類,後面的 productviewModel 類繼承它,在 View 部分綁定時需要綁定的是 ProductCollection 的數據到某個 DataGrid 或者是自定義的模板等。
6. View 界面的完成:
這部分我試着去使用 Style 和 LinearGradientBrush 傷的來做個好看點頁面,很費勁,建議你使用 blend 。
有 3 個 UserControl:
1. Banner:
< UserControl.Resources >
<!-- Main var that runs accross the banner-->
< Style x : Key = "BannerBar" TargetType = "Rectangle" >
< Setter Property = "Stroke" Value = "Black" />
< Setter Property = "Fill" >
< Setter.Value >
< LinearGradientBrush EndPoint = "0.5,1" StartPoint = "0.5,0" >
< GradientStop Color = "#FFCDCDCD" Offset = "0.02" />
< GradientStop Color = "#FF9D9D9D" Offset = "0.07" />
< GradientStop Color = "#FF5D5D5D" Offset = "0.45" />
< GradientStop Color = "#FF282828" Offset = "0.55" />
< GradientStop Color = "#FF121212" Offset = "1" />
</ LinearGradientBrush >
</ Setter.Value >
</ Setter >
</ Style >
<!-- Inlay where banner text sits-->
< Style x : Key = "BannerInlay" TargetType = "Rectangle" >
< Setter Property = "RadiusX" Value = "6" />
< Setter Property = "RadiusY" Value = "6" />
< Setter Property = "Fill" >
< Setter.Value >
< LinearGradientBrush EndPoint = "0.5,1" StartPoint = "0.5,0" >
< GradientStop Color = "#FF666868" Offset = "0" />
< GradientStop Color = "Black" Offset = "1" />
</ LinearGradientBrush >
</ Setter.Value >
</ Setter >
< Setter Property = "Stroke" >
< Setter.Value >
< LinearGradientBrush EndPoint = "0.5,1" StartPoint = "0.5,0" >
< GradientStop Color = "Black" Offset = "0" />
< GradientStop Color = "#FF949494" Offset = "1" />
</ LinearGradientBrush >
</ Setter.Value >
</ Setter >
</ Style >
<!--Texted displayed in the banner-->
< Style x : Key = "BannerInlayText" TargetType = "TextBlock" >
< Setter Property = "FontSize" Value = "20" />
< Setter Property = "FontWeight" Value = "Bold" />
< Setter Property = "Foreground" >
< Setter.Value >
< LinearGradientBrush EndPoint = "0.5,1" StartPoint = "0.5,0" >
< GradientStop Color = "White" Offset = "0" />
< GradientStop Color = "#FF868686" Offset = "1" />
</ LinearGradientBrush >
</ Setter.Value >
</ Setter >
</ Style >
</ UserControl.Resources >
< Grid >
< Rectangle Height = "50" Style ="{ StaticResource BannerBar } " />
< Rectangle HorizontalAlignment = "Center" Height = "40" Margin = "5" Width = "260" Style ="{ StaticResource BannerInlay } " />
< TextBlock HorizontalAlignment = "Center" Height = "50" Text = "Product management" Style ="{ StaticResource BannerInlayText } " />
</ Grid >
2. Detail 頁面:
3. 主頁面:
Banner 是加在主頁面的一個表頭部分。
Detail 頁面時在主頁面上的按鈕點擊時纔會出現的。
比如點擊了 Add Product:
// product
Product product = new Product();
DetailsPage details = new DetailsPage();
details.ProductViewModel = viewModel;
details.DataContext = product;
details.DialogClosed += ( s, a) =>
{
if ( details.DialogResult == DialogResult.Ok)
{
this.viewModel.Addproduct( product);
HtmlPage.Window.Alert( "A new product has been added successfully");
}
tpWorkspace.Items.Remove(( s as UserControl) .Parent);
};
this.AddTab( details, "Adding new product...");
在 Tab 部分添加一個 item 。。。。
7. 數據的綁定
綁定就比較簡單了,在頁面的 Resources 中添加上 ViewModel, 然後在下面的控件中就可以綁定數據了。
說得不夠詳細,大家可以自己看看代碼。
Cheers