博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

稳扎稳打Silverlight(52) - 4.0绑定之 ICommand 命令和 MVVM 模式

Posted on 2010-09-13 08:29  webabcd  阅读(8035)  评论(6编辑  收藏

[索引页]
[源码下载]


稳扎稳打Silverlight(52) - 4.0绑定之 ICommand 命令和 MVVM 模式



作者:webabcd


介绍
Silverlight 4.0 MVVM 模式:

  • ICommand - 命令。可以将其绑定到 ButtonBase 或 Hyperlink 的 Command 属性上 
  • MVVM 模式 - Model-View-ViewModel 



在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html


示例
1、演示 ICommand 的应用
MyCommand.cs

代码
/*
 * ICommand - 命令。可以将其绑定到 ButtonBase 或 Hyperlink 的 Command 属性上
 *     bool CanExecute(object parameter) - 当请命令是否可以执行
 *     event EventHandler CanExecuteChanged - 当请命令是否可以执行的状态发生改变时所触发的事件
 *     void Execute(object parameter) - 当前命令被执行时,所调用的方法
 
*/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight40.Binding.Command
{
    
public delegate void Execute(object parameter);
    
public delegate bool CanExecute(object parameter);

    
public class MyCommand : ICommand
    {
        
private Execute _executeMethod;
        
private CanExecute _canExecuteMethod;

        
public MyCommand()
            : 
this(nullnull)
        {

        }

        
public MyCommand(Execute executeMethod)
            : 
this(executeMethod, null)
        {

        }

        
public MyCommand(Execute executeMethod, CanExecute canExecuteMethod)
        {
            _executeMethod 
= executeMethod;
            _canExecuteMethod 
= canExecuteMethod;
        }

        
public bool CanExecute(object parameter)
        {
            
if (_canExecuteMethod == null)
                
return true;
            
else
                
return _canExecuteMethod(parameter);
        }

        
public void Execute(object parameter)
        {
            
if (_executeMethod != null)
                _executeMethod(parameter);
        }

        
public event EventHandler CanExecuteChanged;

        
protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            
if (CanExecuteChanged != null)
                CanExecuteChanged(
this, e);
        }

        
public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged(EventArgs.Empty);
        }
    }
}


MyViewModel.cs

代码
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight40.Binding.Command
{
    
public class MyViewModel
    {
        
// 声明一个 ICommand 类型,用于绑定到 ButtonBase 或 Hyperlink 的 Command 属性上
        public ICommand Hello { getset; }

        
public MyViewModel()
        {
            
// 绑定了 Hello 的命令被执行时则会调用 ExecuteHello(object parameter) 方法
            Hello = new MyCommand(ExecuteHello);
        }

        
private void ExecuteHello(object parameter)
        {
            MessageBox.Show(
"Hello: " + parameter.ToString());
        }
    }
}


Demo.xaml

代码
<navigation:Page x:Class="Silverlight40.Binding.Command.Demo" 
           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:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           xmlns:ViewModel
="clr-namespace:Silverlight40.Binding.Command"
           Title
="Demo Page">
    
<Grid x:Name="LayoutRoot">
        
        
<Grid.DataContext>
            
<ViewModel:MyViewModel />
        
</Grid.DataContext>

        
<!--
            Command - 指定需要关联的命令
            CommandParameter - 传递给 Command 的参数
        
-->
        
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal" Height="20">
            
<TextBox Name="txtName" Text="webabcd" />
            
<Button Content="Hello" Command="{Binding Hello}" CommandParameter="{Binding ElementName=txtName, Path=Text }" />
        
</StackPanel>
        
    
</Grid>
</navigation:Page>



2、MVVM 模式的 Demo
UpdateCommand.cs

代码
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight40.Binding.MVVM
{
    
// 实现 ICommand 接口,在 MVVM 中它的作用是为 ButtonBase 或 Hyperlink 提供相应的行为逻辑

    
public class UpdateCommand : ICommand
    {
        
private ProductViewModel _viewModel;

        
public UpdateCommand(ProductViewModel viewModel)
        {
            _viewModel 
= viewModel;
        }

        
public bool CanExecute(object parameter)
        {
            
return true;
        }

        
public event EventHandler CanExecuteChanged;

        
public void Execute(object parameter)
        {
            _viewModel.Update();
        }
    }
}


ProductViewModel.cs

代码
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.ComponentModel;

namespace Silverlight40.Binding.MVVM
{
    
// MVVM 之 ViewModel - 为了数据的绑定需要实现 INotifyPropertyChanged 接口;为了命令的绑定需要有相对应的 ICommand 类型的属性

    
public class ProductViewModel : INotifyPropertyChanged
    {
        
public ProductViewModel()
            : 
this (13"wii")
        {
           
        }

        
public ProductViewModel(int productId, string name)
        {
            _productId 
= productId;
            _name 
= name;
        }

        
private int _productId;
        
public int ProductId
        {
            
get { return _productId; }
            
set
            {
                _productId 
= value;
                RaisePropertyChangedEvent(
"ProductId");
            }
        }

        
private string _name;
        
public string Name
        {
            
get { return _name; }
            
set
            {
                _name 
= value;
                RaisePropertyChangedEvent(
"Name");
            }
        }

        
public event PropertyChangedEventHandler PropertyChanged;

        
private void RaisePropertyChangedEvent(string propertyName)
        {
            
if (PropertyChanged != null)
                PropertyChanged(
thisnew PropertyChangedEventArgs(propertyName));
        }



        
public void Update()
        {
            MessageBox.Show(
string.Format("将 ID 为 {0} 的名称更新为:{1}", _productId, _name));
        }

        
public ICommand UpdateCommand
        {
            
get 
            { 
                
return new UpdateCommand(this); 
            }
        }
    }
}


Demo.xaml

代码
<navigation:Page x:Class="Silverlight40.Binding.MVVM.Demo" 
           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:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           xmlns:vm
="clr-namespace:Silverlight40.Binding.MVVM"
           Title
="Demo Page">
    
<Grid x:Name="LayoutRoot">
        
<Grid.Resources>
            
<!--数据源-->
            
<vm:ProductViewModel x:Key="productViewModel" />
        
</Grid.Resources>

        
<StackPanel HorizontalAlignment="Left" DataContext="{StaticResource productViewModel}">
            
            
<!--绑定属性-->
            
<TextBlock Text="{Binding ProductId}" />
            
<TextBox Text="{Binding Name, Mode=TwoWay}" />

            
<!--绑定命令-->
            
<Button Command="{Binding UpdateCommand}" Content="更新" />
            
        
</StackPanel>
    
</Grid>
</navigation:Page>



OK
[源码下载]