• WPF学习08:MVVM 预备知识之COMMAND


        WPF内建的COMMAND是GOF 提出的23种设计模式中,命令模式的实现。

        本文是WPF学习07:MVVM 预备知识之数据绑定的后续,将说明实现COMMAND的三个重点:ICommand  CommandManager InputBindings

    COMMAND简介

        一般情况我们应用设计如下,一个个控件的各类Handler直接关心了如何实现具体的应用逻辑。

        image

        借助COMMAND,我们将具体实现的应用逻辑放在COMMAND中实现,控件只需要绑定相应的COMMAND,而无需关心应用逻辑,从而实现界面与应用逻辑的解耦。

        image

        WPF内建的COMMAND除了提供了逻辑解耦外,还可以用来实现控件使能管理、命令的历史记录(使操作可撤销)。

        本文将介绍如何在MVVM下运用COMMAND,以及控件的使能管理。历史记录功能将在下篇学习笔记中再介绍。


     

    例子

        由CheckBox 管理Command是否可以被执行,Ctrl + A与按键被按均能执行同样的业务逻辑。

        imageimageimage

        XAML代码:

    <Window x:Class="Commands.CommandBlog"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="CommandBlog" Height="300" Width="300">
        <Window.InputBindings>
            <KeyBinding Key="A" Modifiers="Control" Command="{Binding NewFile}"></KeyBinding>
        </Window.InputBindings>
        <StackPanel Background="White">
            <Button Command="{Binding NewFile}">New file</Button>
            <CheckBox IsChecked="{Binding NewFileEnable}" HorizontalAlignment="Center">New file Function Enable</CheckBox>
        </StackPanel>
    </Window>
     

        界面部分后台代码,只需要配置DataContext即可:

    public partial class CommandBlog : Window
    {
        public CommandBlog()
        {
            InitializeComponent();
            DataContext = new CommandBlogViewModel();
        }
    }

        CommandBlogViewModel:

    class CommandBlogViewModel:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ICommand NewFile
        {
            get;
            private set;
        }
    
        public CommandBlogViewModel()
        {
            NewFile = new NewFileCommand(this);
        }
    
        private Boolean newFileEnable;
    
        public Boolean NewFileEnable
        {
            get { return newFileEnable; }
            set 
            { 
                newFileEnable = value;
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("NewFileEnable"));
            }
        }
    }

        NewFileCommand:

    class NewFileCommand : ICommand
    {
        private CommandBlogViewModel commandBlogViewModel;
    
        public NewFileCommand(CommandBlogViewModel commandBlogViewModel)
        {
            this.commandBlogViewModel = commandBlogViewModel;
        }
    
        public bool CanExecute(object parameter)
        {
            return this.commandBlogViewModel.NewFileEnable;
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    
        public void Execute(object parameter)
        {
            MessageBox.Show("New");
        }
    }


     

    ICommand 

    // Summary:
    //     Occurs when changes occur that affect whether or not the command should execute.
    event EventHandler CanExecuteChanged;
    
    // Summary:
    //     Defines the method that determines whether the command can execute in its
    //     current state.
    bool CanExecute(object parameter);
    // Summary:
    //     Defines the method to be called when the command is invoked.
    void Execute(object parameter);

        CanExecute与Execute的意思都很明显,可以在刚才的例子中看出来。这里重点介绍一下如何给它们传参。

        我们可以通过设置CommandParameter向两者传参:
        例子:

    <!--主窗体起名为MainWindow-->
    <Button Command="{Binding NewFile}" CommandParameter="{Binding ElementName=MainWindow}">New file</Button>
       
    public void Execute(object parameter)
    {
        var inputElement = parameter as IInputElement;
        if (inputElement!= null)
        {
            var pos = Mouse.GetPosition(inputElement);
        }
    }

       


     

    CommandManager

        为了使WPF能够自动识别CanExecute的变化,我们需要手动对CanExecuteChanged加以下代码:   

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

     

    InputBindings

        当我们希望可以自定义命令的输入映射时,需要用到InputBindings:

        例子:

    <Window.InputBindings>
        <KeyBinding Key="A" Modifiers="Control" Command="{Binding NewFile}"></KeyBinding>
        <KeyBinding Key="C" Modifiers="Control" Command="{Binding CopyContent}"></KeyBinding>
        <KeyBinding Key="V" Modifiers="Control" Command="{Binding PasteContent}"></KeyBinding>
        <KeyBinding Key="F1" Modifiers="Control" Command="{Binding HelpPrompt}"></KeyBinding>
    </Window.InputBindings>
  • 相关阅读:
    redis list 清空记录小技巧
    fastJson 之 JSONPath使用
    【移动开发】怎样自己定义ViewGroup
    POJ 3255 Roadblocks
    java带图片的邮件发送方法实现
    android学习二(Activity)
    OpenWRT加入 crontab开机默认运行
    ubuntu14.04启动提示set_sw_state failed
    jekyll bootstrap更改主题theme
    windows API 实现截图
  • 原文地址:https://www.cnblogs.com/E-WALKER/p/4409420.html
Copyright © 2020-2023  润新知