• 案例分析 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;

            
    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 { getset; }

            
    // 1 new instance per View 
            public CheckoutViewModel Checkout
            {
                
    get { return new CheckoutViewModel(_sp.PageConductor, _sp.BookDataService); }
            }
        }
    }

     为什么需要一个ViewModelLocator来连结ViewModel 和View 呢?

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

       通过ViewModelLocator 为viewModel 提供一个 ServiceProviderBase 

    那么这个ServiceProviderBase 又是做什么的呢?
     
    3.3 ViewModel如何与Model关联
          ServiceProviderBase 管理所有的 数据提供的服务。
    namespace BookShelf {
        
    public abstract class ServiceProviderBase {
            
    public virtual IPageConductor PageConductor { getprotected set; }
            
    public virtual IBookDataService BookDataService { getprotected 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 class ServiceProvider : ServiceProviderBase
        {
            
    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)

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

    3.4 ViewModel中的Command

        继承自 RelayCommand
     RelayCommand 封装了 普通的Icommand 添了一个判断 是否 执行的参数而已。确是很好用。  
     
     3.5不同的View之间的沟通
    我们可以BookView.xaml里找到EDIT 的button 然后去看
     
    //Command
      public RelayCommand EditBookCommand { getset; }
    //EditBookCommand 里要执行的方法
      
    private void OnEditBook()
            {
                Messenger.Default.Send(new LaunchEditBookMessage() { Book = SelectedBook });
            }
    //
    internal class LaunchEditBookMessage : MessageBase
        {
            
    public Book Book { getset; }
        }
     去到对应的View
     DataContext="{Binding Book, Source={StaticResource Locator}}" 
     
         
    <Grid Name="grid1" DataContext="{Binding SelectedBook}">
     看到这里的时候你可以想象,他为什么要提供一个全局的单例,其实类似于一个全局的概念把
    所有的关于BOOK的都集中到这个viewModel,当然这样做有争议,我也不知道自己的理解是否正确。
     
    3.6更多
    由于我不懂MVVMLight TOOLkit。有些东西不能够深入去说出来。过几天等我再认真看一下他的源码再跟大家分享。
     
     4相关资源
     我的wiki上关于 MVVM的词条 
     PPT
    我整理其他的关于 MVVM的高质量的文章 部分英文加了中文注释

     
  • 相关阅读:
    常用Git代码托管服务分享
    .NET中操作IPicture、IPictureDisp
    Git学习笔记与IntelliJ IDEA整合
    螺旋队列问题
    杂题3道
    .NET 配置文件简单使用
    C++之Effective STL
    不容易理解的 lock 和 merge
    状态模式
    观察者模式
  • 原文地址:https://www.cnblogs.com/facingwaller/p/1865668.html
Copyright © 2020-2023  润新知