WPF 08: COMMAND for MVVM preparation, wpfmvvm
The built-in COMMAND of WPF is the implementation of the COMMAND mode in 23 design modes proposed by GOF.
This article is a follow-up of WPF learning 07: MVVM preparation knowledge-Data Binding. It will show three key points of COMMAND implementation: ICommand CommandManager InputBindings
COMMAND Introduction
In general, the application design is as follows. Handler of various controls directly cares about how to implement specific application logic.
With COMMAND, we place the specific application logic in COMMAND for implementation. The control only needs to bind the corresponding COMMAND, without having to care about the application logic, so as to decouple the interface from the application logic.
In addition to logical decoupling, the built-in wpf command can also be used to implement control management and COMMAND history (so that the operation can be undone ).
This article describes how to use COMMAND and control enabling management in MVVM. The history function will be introduced in the next study note.
Example
The CheckBox manages whether the Command can be executed. Both Ctrl + A and the press key can execute the same business logic.
XAML code:
<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>
Some background code on the interface, you only need to configure 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);
Both CanExecute and Execute have obvious meanings, which can be seen in the example just now. Here we will focus on how to pass parameters to them.
We can set CommandParameter to pass Parameters to both of them:
Example:
<! -- The main form is named 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
To enable WPF to automatically identify CanExecute changes, we need to manually code CanExecuteChanged:
public event EventHandler CanExecuteChanged{ add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; }}
InputBindings
When we want to customize the input ing of commands, we need to use InputBindings:
Example:
<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>