案例分析 BookShelf 概览(MVVM)
2010-10-31 22:38 撞破南墙 阅读(2680) 评论(7) 编辑 收藏 举报1 介绍案例
2 介绍MVVM和RIA Services
2.1MVVM
2.2RIA Services
3 正式开始
3.1 目录结构
3.2 View如何与ViewModel关联
3.3 ViewModel如何与Model关联
3.4 ViewModel中的Command
3.5 不同的View之间的沟通
3.6。。。。更多下次吧
4 相关资源
1 介绍案例
该例子是来自 Kung Fu 在PDC 2010 中的 Silverlight 使用MVVM和RIA Services的一个展示 :
《Patterns and Practices with MVVM and RIA Services》
摘要:
学习使用 RIA SERVICE 与 开发方式的结合,如 代理服务,单例责任模式?,命令方式(Command),用户互动,消息方法,子窗口,设计时的数据显示,测试和开发使用 MVVM 模式,建立一个Silverlight和WP的应用程序。
(翻译得很烂,真是英文太不好了。抱歉,附原文希望会的指正)
Learn about the rewards of using RIA Services together with development patterns, such as the Service Providers, Single Responsibility pattern, Commanding, user Interactions, Messaging, ChildWindows, Design Time Data, Testing, and developing using the Model-View-ViewModel (MVVM) pattern, to build Silverlight and Windows Phone applications. Hear the top tips you need to know for building data driven Silverlight applications that solve real world problems.
2 介绍下MVVM和RIA Services
2.1 MVVM
2.2 RIA Services
更多参考MSDN
http://www.cnblogs.com/facingwaller/archive/2010/09/26/1836147.html
3 进入正题
3.1 目录结构
3.2 View如何与ViewModel关联
在Views文件下下面的BookView.xaml页面中的 page标签里
DataContext="{Binding Book, Source={StaticResource Locator}}"
并且F12进去可以看到
xmlns:local="clr-namespace:BookShelf"
>
<local:ViewModelLocator x:Key="Locator" />
由此可知,View和ViewModel之间通过 ViewModelLocator 来连结
{
public class ViewModelLocator
{
private readonly ServiceProviderBase _sp;
public ViewModelLocator()
{
_sp = ServiceProviderBase.Instance;
// 1 VM for all places that use it. Just an option 一个Book的单例
Book = new BookViewModel(_sp.PageConductor, _sp.BookDataService);
}
public BookViewModel Book { get; set; }
// 1 new instance per View
public CheckoutViewModel Checkout
{
get { return new CheckoutViewModel(_sp.PageConductor, _sp.BookDataService); }
}
}
}
为什么需要一个ViewModelLocator来连结ViewModel 和View 呢?
通过 ViewModelLocator 可以控制是否单例,单例的作用等下会说到。
通过ViewModelLocator 为viewModel 提供一个 ServiceProviderBase
public abstract class ServiceProviderBase {
public virtual IPageConductor PageConductor { get; protected set; }
public virtual IBookDataService BookDataService { get; protected set; }
private static ServiceProviderBase _instance;
public static ServiceProviderBase Instance {
get { return _instance ?? CreateInstance(); }
}
static ServiceProviderBase CreateInstance() {
// TODO: Uncomment 判断是否在设计工具使用下
return _instance = DesignerProperties.IsInDesignTool ?
(ServiceProviderBase)new DesignServiceProvider() : new ServiceProvider();
}
}
}
在这里他提供了基于抽象类ServiceProviderBase 的两个不同的实现。见下图
这是一个这样的模型。。类似以下的模式图 .这里有一个很好的点子就是让他可以在通过一个
DesignerProperties.IsInDesignTool
判断是否在设计模式下,从而使得设计模式下也可以返回数据。。。
继承ServiceProviderBase是具体提供实现的IPageConductor。IBookDataService 的 类
{
public ServiceProvider()
{
// Do this if you want one service for your app.
//PageConductor = new PageConductor();
}
// Do this if you want one service per VM instance for your app.
public override IPageConductor PageConductor
{
get { return new PageConductor(); }
}
public override IBookDataService BookDataService
{
get { return new BookDataService(); }
}
}
他的好处显而易见,
1数据服务依赖接口(从而可以切换RIA SERVICE或者 WCF SERVICE)
3.4 ViewModel中的Command
private void OnEditBook()
{
Messenger.Default.Send(new LaunchEditBookMessage() { Book = SelectedBook });
}
//而
internal class LaunchEditBookMessage : MessageBase
{
public Book Book { get; set; }
}
去到对应的View
<Grid Name="grid1" DataContext="{Binding SelectedBook}">
看到这里的时候你可以想象,他为什么要提供一个全局的单例,其实类似于一个全局的概念把
作者:撞破南墙
出处:http://www.cnblogs.com/facingwaller/
关于作者:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。