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

那么这个ServiceProviderBase 又是做什么的呢?
 
3.3 ViewModel如何与Model关联
      ServiceProviderBase 管理所有的 数据提供的服务。
namespace  BookShelf {
    
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   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 {  get set ; }
//EditBookCommand 里要执行的方法
  
private   void  OnEditBook()
        {
            Messenger.Default.Send( new  LaunchEditBookMessage() { Book  =  SelectedBook });
        }
//
internal   class  LaunchEditBookMessage : MessageBase
    {
        
public  Book Book {  get set ; }
    }

 

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

 

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述 有一个长度为 $n$ 的书架,每本书有一个高度 $h_i$。现在你可以进行以下两种操作: - 将一本书放在书架的最左边或最右边,花费为 $c_1$。 - 将一本高度为 $h_i$ 的书放在一本高度为 $h_j$ 的书的上面,花费为 $c_2$。 现在你需要将书架上的书按照高度从小到大排列,求最小花费。 输入格式 第一行包含三个整数 $n,c_1,c_2$。 第二行包含 $n$ 个整数 $h_i$。 输出格式 输出一个整数,表示最小花费。 数据范围 $1\leq n\leq 200,1\leq c_1,c_2\leq 10^9,1\leq h_i\leq 10^9$ 输入样例 5 1 2 3 1 4 2 5 输出样例 6 算法1 (动态规划) $O(n^2)$ 首先考虑一个朴素的 dp,设 $f_{i,j}$ 表示前 $i$ 本书已经排好序,第 $i+1$ 本书放在第 $j$ 个位置的最小花费。 状态转移方程为: $$ f_{i,j}=\min\{f_{i-1,k}+c_1\}+\begin{cases}&\text{if }h_{i+1}>h_j\\c_2&\text{otherwise}\end{cases} $$ 其中 $k$ 取遍 $1\sim i$,表示将第 $i+1$ 本书放在第 $k$ 个位置。 时间复杂度 $O(n^3)$ C++ 代码 算法2 (单调队列优化) $O(n^2)$ 考虑优化上述 dp,发现状态转移方程中的 $\min$ 操作可以用单调队列优化,具体来说,我们维护一个单调递增的队列 $q$,其中 $q_i$ 表示第 $i$ 个位置的最小花费,那么对于状态 $f_{i,j}$,我们只需要找到 $q$ 中第一个大于等于 $f_{i-1,k}+c_1$ 的位置 $p$,然后 $f_{i,j}=q_p+\begin{cases}&\text{if }h_{i+1}>h_j\\c_2&\text{otherwise}\end{cases}$。 时间复杂度 $O(n^2)$ C++ 代码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值