Silverlight中使用MVVM(5):Command II

       Silverlight中使用MVVM(1)--基础

       Silverlight中使用MVVM(2)—提高

       Silverlight中使用MVVM(3)—进阶

       Silverlight中使用MVVM(4)—演练

          

        大约半年前,我接触了MVVM这个概念,经过一段时间的运用后,对MVVM已经有了更为深刻的了解,这篇文章将重新回头来看Command,因为Command是

实现MVVM中非常重要的一个环节。

         在SL4中,只提供了对Button与Hyperlink的内置Command,简单的来讲,在SL中使用内置的Command有3个步骤:

         1,实现ICommand接口的类

         2,在ViewModel中创建一个ICommand属性

         3,将第2步中创建的属性绑定到Button或Hyperlink中

         我下面首先通过“点击Button增加数据”这样一个简单的例子说明一下这个流程,因为本意是给刚接触MVVM的朋友看的,如果不是太熟悉MVVM,可以先看下

博客中前面几篇相关文章。

         在实际项目中,对每个Command都实现相应的类是不现实的,所以这里直接以泛型类的方式实现ICommand接口,

        public class DelegateCommand<T> : ICommand
     {
        private readonly Action<T> executeAction;
        private readonly Func<T, bool> canExecuteAction;
        public event EventHandler CanExecuteChanged;
        public DelegateCommand(Action<T> executeAction)
            : this(executeAction, null)
        {
        }
        public DelegateCommand(Action<T> executeAction,
            Func<T, bool> canExecuteAction)
        {
            this.executeAction = executeAction;
            this.canExecuteAction = canExecuteAction;
        }
        public bool CanExecute(object parameter)
        {
            if (canExecuteAction != null)
            {
                return canExecuteAction((T)parameter);
            }
            return true;
        }
        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                executeAction((T)parameter);
            }
        }
     }

           这个部分主要是参考的Prism框架的,在网上搜DelegateCommand会看到一大堆这方面的讲解,就不对代码细说了。

          在实现ViewModel部分前,先定义一个实体类Employee

       public class Employee
      {
        public string EmpName { get; set; }
        public int Age { get; set; }
        public override string ToString()
        {
            return EmpName + ":" + Age;
        }
       }

         ViewModel部分主要是声明一个AddCommand属性,并给其指派方法

       public class EmployeeViewModel
    {
        public ICommand AddCommand { get; set; }
        public ObservableCollection<Employee> EmpList { get; set; }
        public  EmployeeViewModel()
        {
            EmpList = new ObservableCollection<Employee>
                          {
                              new Employee {Age = 23, EmpName = "Ringgo"},
                              new Employee {Age = 23, EmpName = "Jim"}
                          };
           AddCommand = new DelegateCommand<Employee>(AddMethod);
        }
      
        private void AddMethod(Employee employee)
        {        
            EmpList.Add(new Employee { Age = 24, EmpName = "White" });
        }
    }

        View的只有2行XAML:

        <Button Content="点击" Command="{Binding   AddCommand}"/>
        <ListBox ItemsSource="{Binding EmpList,Mode=OneWay}" />
    这时点击Button时,你会发现AddCommand已经起作用了,新增的记录出现在了ListBox。

上面的例子是对内置支持Comand控件的做法(开头提到内置的Command只能对继承于ButtonBase的控件有效),

对于其它的控件,则需要用到Blend4中的InvokeCommandAction。

下面在前面例子的基础上进行修改,

实现的效果很简单

2 即显示ListBox的选中项信息

下面实现这个部分的功能,首先在ViewModel里面添加相关的ICommand属性

         public ICommand SelectCommand { get; set; }
         private void SelectMethod(Employee employee)
        {
            MessageBox.Show(employee.EmpName);
        }
         public  EmployeeViewModel()
        {  //...
           SelectCommand = new DelegateCommand<Employee>(SelectMethod);
        }

因为这篇文章不是讲Blend的,所以我不会太多关注Blend在这个部分的应用,我简单的演示下步骤

首先在Blend中打开该解决方案

打开Assets选项卡:

3 选中InvokeCommandAction,将其拖动到listBox1后,选中listBox1下的InvokeCommandAction

4 5

打开属性选项卡,修改EventName为MouseLeftButtonUp

6

现在开始绑定到Command,点击Data bind会弹出对话框

7

选中+CLR Object创建数据源

8 选中创建好的EmployeeViewModel,

9

 

这几步都做好后,你可以看看生成的Xaml,关键的Xaml代码是这样的:

        <i:Interaction.Triggers>
        		<i:EventTrigger EventName="MouseLeftButtonUp">
                    <i:InvokeCommandAction Command="{Binding SelectCommand}"/>
        		</i:EventTrigger>
        </i:Interaction.Triggers>

这里需要将ListBox的SelectItem作为SelectCommand关联的SelectMethod(Employee employee)的参数:

       <i:InvokeCommandAction 
		CommandParameter="{Binding SelectedItem, ElementName=listBox1}" 
                  Command="{Binding SelectCommand}"/>

这样就完成了使用InvokeCommandAction实现了对SL4中不内置支持Command的控件,对于InvokeCommandAction还有其它的一些应用,可以自己去看

相关文章。

通过这一系列步骤,可以看到MVVM模式可以将UI与逻辑很好的分开维护,使用MVVM的这半年来,我在工作中越来越倾向于应用这种模式,希望这篇文章

能给大家有所帮助。

代码下载:SLCommandInMVVM.rar

 

posted @ 2011-03-07 09:54  ringgo  阅读(8867)  评论(6编辑  收藏  举报