zoukankan      html  css  js  c++  java
  • (Translation)Silverlight 4 and MVVM pattern with ICommand

    转自:http://www.cnblogs.com/888h/archive/2010/11/09/1873057.html

    方便理解 MVVM  

    什么是MVVM模式

      MVVM(Model-View-ViewModel)是专为WPF和SilverLight设计的开发模式。它为程序员指定了一个开发准则,也就是开发出来的程序应该能达到更的单元测试、程序调试、易管理及程序的可读性。

       View层的要实现零代码,也就是在UI的mainpage.xaml.cs中没有任何代码。也就是要达到以下要求:确定和取消的按钮不能在后台有click事件,没有form或者windows的Load逻辑代码,没有UI的binding的逻辑代码,没有UI的验证代码以及没有类型转换代码。

          如果要达到MVVM模式的UI后台隐藏文件没有任何逻辑代码以及实现显示层和逻辑层的松藕型。那么必须得有以下特性:

       1、WPF和SilverLight的UI层(XAML)的双向绑定能力

       2、绑定的数值转换能力(例如:string类转换为Color类)

       3、INotification和Dependency属性

       4、Data Context对象

           5、Static Resources

       6、接口ICommand,此接口可以实现后台代码没有事件

       7、在XAML中对Validation=true利用(显示层)  

      在没有MVVM模式之前,有两个比较有名的模式,一个是在winform和WPF广泛应用的WVP模式(尽管它不能很好的利用WPF的双向绑定(Two Way Binding))。另一个是在ASP.NET应用程序中一直使用的MVC。

      在没有MVVM模式的情况,那么程序员在写Winform或者WPF/SilverLight应用程序时。格式会是以下的情况。

       1、显示层和后台逻辑代码是紧藕型的

       2、如果UI层改变时,那么后台逻辑代码也得跟着改变。

       3、不能让多个表示层同享一个逻辑层

       4、因为显示层和和后台逻辑代码是紧藕型的,所以不能编写单元测试

       5、在没有使用MVVM模式时,WPF的显示层(XAML)被看作是数据层

       下面来看看使用MVVM模式之后,有什么优点

      1、表示层和数据层完全分离,表示层中没有数据层代码,仅仅是为了显示数据

      2、容易编写单元测试和管理代码

      3、XMAL.CS中没有代码,因为表示层和逻辑层是松藕型的

      4、SilverLight4.0对接口ICommand的支持(这个对我们写事件有很大帮助)

      下面用MVVM举一个简单的例子,我们用一个TextBox显示用户名,一个TextBox显示年龄,当点击按钮时,年龄随着增长,至到26.

      第一步:在Viual Studio2010中建一个名为"simplePersonandageMVVM"的SilverLight应用程序

      第二步:新增一个类文件,命名为"PersonModel",然后粘贴下面的代码(这是数据对像的实例)

     

    代码
    using System.ComponentModel;

    namespace simplePersonandageMVVM
    {
       
        
    public class PersonModel : INotifyPropertyChanged
        {
            
    string name;
            
    public string Name
            {
                
    get { return this.name; }
                
    set
                {
                    
    this.name = value;
                    fire(
    "Name");

                }
            }
            
    int age;
            
    public int Age
            {
                
    get { return this.age; }
                
    set
                {
                    
    this.age = value;
                    fire(
    "Age");
                }
            }
            
    public PersonModel() { }
            
    public PersonModel(string name, int age)
            {
                
    this.name = name;
                
    this.age = age;
            }

            
    public void fire(string x)
            {
                
    if (PropertyChanged != null)
                {
                    PropertyChanged(
    thisnew PropertyChangedEventArgs(x));
                }
            }
            
    public event PropertyChangedEventHandler PropertyChanged;
        }


      第三步:创建另一个类文件,命名为PersonViewModel.cs",这个是ViewModel,它的作用是连接View(表示层)和实例(实体层)的通信。

      

    代码
    namespace simplePersonandageMVVM
    {
        
    public class PersonViewModel
        {
            
    public PersonModel p { getset; }
            
    public PersonViewModel()
            {
                p 
    = new PersonModel("prabjot"20);                     
            }

            
    public ICommand GetPerson
            {
                
    get { return new GetPersonCommand(this); }
            }
            
            
    public void Increaseage(PersonModel d)
            {
                d.Age
    ++;           
                
    string x = d.Age.ToString();           
                MessageBox.Show(x);       
            
            }
        }
    }

      第四步:创建一个继承于接口ICommand的Command对象,命名为"GetPersonCommand.cs",这个类重写了接口ICommand的两个方法。一个是方法当按钮设置为Enable时才起作用的CanExecute,另一个方法是执行按钮Click事件的Execute.

    代码
      namespace simplePersonandageMVVM
    {
        
    public class GetPersonCommand : ICommand
        {
            PersonViewModel pincommand;
            
    public GetPersonCommand( PersonViewModel Pcame)
            { 
              pincommand
    = Pcame;
               
               
            }

            
    public bool CanExecute(object parameter)
            {
               
    if(pincommand.p.Age > 25)
               {
                   
    return false ;
               }
            
    else
               {
                   
    return true;
               }
                
            }

            
    public event EventHandler CanExecuteChanged;

            
    public void Execute(object parameter)
            {
               pincommand.Increaseage(pincommand.p);
            }
        }
    }
      

      第五步:是XAML文件,代码如下:

     

    代码
    <UserControl x:Class="simplePersonandageMVVM.MainPage"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:local
    ="clr-namespace:simplePersonandageMVVM"
        mc:Ignorable
    ="d"
        d:DesignHeight
    ="300" d:DesignWidth="400">
        
    <UserControl.Resources>
            
    <local:PersonViewModel  x:Key="pkey" />
        
    </UserControl.Resources>
        
        
    <Grid x:Name="LayoutRoot" Background="White" 
              DataContext
    ="{Binding Source={StaticResource pkey}}" >
            
    <Grid Name="hi" DataContext="{Binding Path=p, Mode=TwoWay}">
                
    <TextBox Height="23" HorizontalAlignment="Left" Margin="53,30,0,0" 
                     Name
    ="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=Name, Mode=TwoWay}" />
                
    <TextBox Height="23" HorizontalAlignment="Left" Margin="53,68,0,0" Name="textBox2" 
                     Text
    ="{Binding Path=Age, Mode=TwoWay}"  VerticalAlignment="Top" Width="120" />
                
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="53,112,0,0" Name="button1"
                    VerticalAlignment
    ="Top" Width="75"  Command="{Binding Path=DataContext.GetPerson, ElementName= LayoutRoot }" 
                        CommandParameter
    ="{Binding Path=Age, ElementName=hi}"  />
          
    </Grid>
        
    </Grid>
          
    </UserControl>

      通过对上面的一个小例子,希望能帮且你理解MVVM模式。也希望对你以后使用MVVM开发WPF或者SilverLight应用程序用帮助。

      因为自己的技术水平和英语水平有限,难免有不足之处,请大家多多指教。

      英文原文地址: http://www.dotnetspider.com/resources/36781-Silverlight-MVVM-pattern-with-ICommand.aspx

  • 相关阅读:
    Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
    旋转二维数组
    replace empty char with new string,unsafe method和native implementation的性能比较
    判断一字符串是否可以另一字符串重新排列而成
    移除重复字符的几个算法简单比较
    也来纠结一下字符串翻转
    判断重复字符存在:更有意义一点
    程序员常去网站汇总
    sublime
    针对程序集 'SqlServerTime' 的 ALTER ASSEMBLY 失败,因为程序集 'SqlServerTime' 未获授权(PERMISSION_SET = EXTERNAL_ACCESS)
  • 原文地址:https://www.cnblogs.com/jeekun/p/2107919.html
Copyright © 2011-2022 走看看