码迷,mamicode.com
首页 > Windows程序 > 详细

【WPF】命令系统

时间:2015-06-07 01:00:42      阅读:388      评论:0      收藏:0      [点我收藏+]

标签:

引言

     在MVVM模式开发下,命令Command是编程中不可或缺的一部分.下面,我分3种场景简单介绍一下命令的用法.

ViewModel中的命令

     在ViewModel定义命令是最常用的用法,开发中几乎90%以上的命令都在用在ViewModel上.怎么用?先从实现ICommand说起,下面定义一个命令

    public class MyCommand :ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            MessageBox.Show("命令已经执行!");
        }
    }

然后在ViewModel中定义一个命令,赋值MyCommand,接着在View绑定命令,如下

    public class MainWindowViewModel
    {
        public MainWindowViewModel()
        {
            myCommand = new MyCommand();
        }
        public ICommand myCommand {get ; set ; }

    }
<Window x:Class="WpfCommand.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfCommand"
        Title="MainWindow" Height="350" Width="525">
    <Grid>      
        <Button Command="{Binding myCommand}"  Name="btn"  Height="30" Width="80" Margin="104,75,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">执行命令</Button>
    </Grid>
</Window>

上面看起来不复杂,但是实际开发绝对不这么干的,如果每个命令都要自定义类,还能好好玩耍么.实际开发,我们可以借助第三方类轻松完成我们的命令实现,如Prism框架的DelegateCommand,MVVMLight的RelayCommand,下面演示一下DelegateCommand,只需在ViewModel中实例化一个命令既可.

 public class MainWindowViewModel
    {
        public MainWindowViewModel()
        {
            myCommand = new DelegateCommand(() => { MessageBox.Show("命令已经执行!"); }, () => true); 
        }
        public ICommand myCommand {get ; set ; }
    }

 自定义控件中的命令绑定

      在自定义控件中绑定命令不常见,但是某些场景下还是有用的.例如DataGrid的新增行,删除行,绑定自定义命令,让外部调用还是很有用的.下面,用继承TextBox做个没什么卵用的演示吧.

      利用CommandManager绑定命令,命令的作用是将字体变成红色,无文本时则命令不可用.MyTextBox定义如下

public  class MyTextBox:TextBox
    {

      static MyTextBox()
      {
          CommandManager.RegisterClassCommandBinding(typeof(MyTextBox),
                  new CommandBinding(MyCommands.MyRoutedCommand,
                  Command_Executed, Command_CanExecute));       
      }

      private static void Command_CanExecute(object sender, CanExecuteRoutedEventArgs e)
      {
          MyTextBox myTextBox = (MyTextBox)sender;
          e.CanExecute = !string.IsNullOrWhiteSpace(myTextBox.Text);  
      }
      private static void Command_Executed(object sender, ExecutedRoutedEventArgs e)
      {
          MyTextBox myTextBox = (MyTextBox)sender;
          myTextBox.Foreground = new SolidColorBrush(Colors.Red);
      }
    }
 public class MyCommands
   {
       private static RoutedUICommand myRoutedCommand;
       static MyCommands()
       {
           myRoutedCommand = new RoutedUICommand(
             "MyRoutedCommand", "MyRoutedCommand", typeof(MyCommands));
       }
       public static RoutedUICommand MyRoutedCommand
       {
           get { return myRoutedCommand; }
       }
   }

如何使用,很简单,设置一下Button的Command和CommandTarget即可,如下

<Window x:Class="WpfCommand.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfCommand"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:MyTextBox  x:Name="mytextbox"></local:MyTextBox>
        <Button Command="local:MyCommands.MyRoutedCommand"  CommandTarget="{Binding ElementName=mytextbox}"  Name="btn"  Height="30" Width="80" Margin="104,75,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">执行命令</Button> </Grid> </Window>

自定义控件中的命令属性

       在WPF的控件库,我们会发现很多控件都带有Command,例如Button.控件中有Command属性才能让我们如期望地执行命令.如果我们的自定义控件想定义这个Command,就要实现ICommandSource了.下面从定义一个简单按钮来演示一下.

public class MyButton : ContentControl,ICommandSource
    {
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register(
                "Command",
                typeof(ICommand),
                typeof(MyButton),
                new PropertyMetadata((ICommand)null,
                new PropertyChangedCallback(CommandChanged)));

        public ICommand Command
        {
            get
            {
                return (ICommand)GetValue(CommandProperty);
            }
            set
            {
                SetValue(CommandProperty, value);
            }
        }
  
        public static readonly DependencyProperty CommandTargetProperty =
            DependencyProperty.Register(
                "CommandTarget",
                typeof(IInputElement),
                typeof(MyButton),
                new PropertyMetadata((IInputElement)null));

        public IInputElement CommandTarget
        {
            get
            {
                return (IInputElement)GetValue(CommandTargetProperty);
            }
            set
            {
                SetValue(CommandTargetProperty, value);
            }
        }

       
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register(
                "CommandParameter",
                typeof(object),
                typeof(MyButton),
                new PropertyMetadata((object)null));

        public object CommandParameter
        {
            get
            {
                return (object)GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        private static void CommandChanged(DependencyObject d,
           DependencyPropertyChangedEventArgs e)
        {

        }
        //在鼠标的按下事件中,调用命令的执行
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);

            if (!Command.CanExecute(CommandParameter))
                return;
            Command.Execute(CommandParameter);
        }
    }

上面只是简单地定义了命令,实际上Button的Command定义要比上面复杂些,有兴趣的童鞋可以去看看Button的源码,推荐一款反编译神器dotPeek.下面是Xaml的定义.

<Window x:Class="WpfCommand.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfCommand"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:MyTextBox  x:Name="mytextbox"></local:MyTextBox>
        <local:MyButton Height="50" Width="80" Command="local:MyCommands.MyRoutedCommand"  CommandTarget="{Binding ElementName=mytextbox}" >
            <Ellipse Fill="Blue">
            </Ellipse>
        </local:MyButton>
    </Grid>
</Window>

 小结

     本着从实际出发的原则,命令的介绍和其他内容被我省略了.最后,如果你有更好的想法,请不吝留言指教.

      

 

【WPF】命令系统

标签:

原文地址:http://www.cnblogs.com/caizl/p/4557417.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!