微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

案例分析 BookShelf 概览(MVVM)

 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进去可以看到 

< ResourceDictionary
         
xmlns:local ="clr-namespace:BookShelf"  
         
>
    
    
local:viewmodelLocator  x:Key ="Locator"   />

由此可知,View和viewmodel之间通过 viewmodelLocator 来连结 

namespace  BookShelf
{
    
public class  viewmodelLocator 
    {
        
private readonly  ServiceProviderBase _sp;

        
 viewmodelLocator()
        {
            _sp 
=  ServiceProviderBase.Instance;

            
//  1 VM for all places that use it. Just an option 一个Book的单例
            Book  new  Bookviewmodel(_sp.PageConductor, _sp.BookDataService); 
        }

        
 Bookviewmodel Book {  get set ; }

        
 1 new instance per View            Checkoutviewmodel Checkout
        {
            
 {  return  Checkoutviewmodel(_sp.PageConductor, _sp.BookDataService); }
        }
    }
}

 为什么需要一个viewmodelLocator来连结viewmodel 和View 呢?

   通过 viewmodelLocator 可以控制是否单例,单例的作用等下会说到。

   通过viewmodelLocator 为viewmodel 提供一个 ServiceProviderBase 

那么这个ServiceProviderBase 又是做什么的呢?
 
3.3 viewmodel如何与Model关联
      ServiceProviderBase 管理所有的 数据提供的服务。
namespace  BookShelf {
    
public   abstract class  ServiceProviderBase {
        
virtual  IPageConductor PageConductor {  get protected set ; }
        
 IBookDataService BookDataService {  ; }

        
private static  ServiceProviderBase _instance;
        
 ServiceProviderBase Instance {
            
 {  return  _instance  ??  CreateInstance(); }
        }

        
 ServiceProviderBase CreateInstance() {
            
//  Todo:  Uncomment 判断是否在设计工具使用下
             =  DesignerProperties.IsInDesignTool  ?                 (ServiceProviderBase) new  DesignServiceProvider() :   ServiceProvider();
        }
    }
}

 在这里他提供了基于抽象类ServiceProviderBase  的两个不同的实现。见下图

这是一个这样的模型。。类似以下的模式图 .这里有一个很好的点子就是让他可以在通过一个

 DesignerProperties.IsInDesignTool 

判断是否在设计模式下,从而使得设计模式下也可以返回数据。。。

 

  继承ServiceProviderBase是具体提供实现的IPageConductor。IBookDataService 的 类

 ServiceProvider : ServiceProviderBase
    {
        
 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.          override  IPageConductor PageConductor
 PageConductor(); }
 IBookDataService BookDataService
 BookDataService(); }
    }

 

 他的好处显而易见,

1数据服务依赖接口(从而可以切换RIA SERVICE或者 WCF SERVICE)

2易于测试
不好
1增大工作量:针对每个方法一个接口,很多人可能无法忍受。
 

3.4 viewmodel中的Command

    继承自 RelayCommand
 RelayCommand 封装了 普通的Icommand 添了一个判断 是否 执行的参数而已。确是很好用。  
 
 3.5不同的View之间的沟通
我们可以BookView.xaml里找到EDIT 的button 然后去看
 
//Command
   public  RelayCommand EditBookCommand {  get set ; }
//EditBookCommand 里要执行的方法
  
private   void  OnEditBook()
        {
            Messenger.Default.Send( new  LaunchEditBookMessage() { Book  =  SelectedBook });
        }
//
internal class  LaunchEditBookMessage : MessageBase
    {
        
 Book Book {  ; }
    }

 

 去到对应的View
 DataContext = " {Binding Book, Source={StaticResource Locator}} "  
 
     
< Grid Name grid1 {Binding SelectedBook} >

 

 看到这里的时候你可以想象,他为什么要提供一个全局的单例,其实类似于一个全局的概念把
所有的关于BOOK的都集中到这个viewmodel,当然这样做有争议,我也不知道自己的理解是否正确。
 
3.6更多
由于我不懂MVVMLight TOOLkit。有些东西不能够深入去说出来。过几天等我再认真看一下他的源码再跟大家分享
 
 4相关资源
 我的wiki上关于  MVVM的词条 
  PPT
我整理其他的关于  MVVM的高质量的文章 部分英文加了中文注释

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐