代码下载:
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