Prism Step7 Command

什么是Command?先看下微软官方的说明:

Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.

命令是Windows Presentation Foundation(WPF)中的一种输入机制,它提供比设备输入更多的语义级别的输入处理。命令示例包括在许多应用程序中发现的“复制”,“剪切”和“粘贴”操作。

MainWindows.xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Window x:Class="UsingDelegateCommands.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="Using DelegateCommand" Width="350" Height="275">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<CheckBox IsChecked="{Binding IsEnabled}" Content="Can Execute Command" Margin="10"/>
<Button Command="{Binding ExecuteDelegateCommand}" Content="DelegateCommand" Margin="10"/>
<Button Command="{Binding DelegateCommandObservesProperty}" Content="DelegateCommand ObservesProperty" Margin="10"/>
<Button Command="{Binding DelegateCommandObservesCanExecute}" Content="DelegateCommand ObservesCanExecute" Margin="10"/>
<Button Command="{Binding ExecuteGenericDelegateCommand}" CommandParameter="Passed Parameter" Content="DelegateCommand Generic" Margin="10"/>
<TextBlock Text="{Binding UpdateText}" Margin="10" FontSize="22"/>
</StackPanel>
</Window>

MainWindowViewModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using System;
using Prism.Commands;
using Prism.Mvvm;

namespace UsingDelegateCommands.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
SetProperty(ref _isEnabled, value);
ExecuteDelegateCommand.RaiseCanExecuteChanged();
}
}

private string _updateText;
public string UpdateText
{
get { return _updateText; }
set { SetProperty(ref _updateText, value); }
}

public DelegateCommand ExecuteDelegateCommand { get; private set; }

public DelegateCommand<string> ExecuteGenericDelegateCommand { get; private set; }

public DelegateCommand DelegateCommandObservesProperty { get; private set; }

public DelegateCommand DelegateCommandObservesCanExecute { get; private set; }


public MainWindowViewModel()
{
ExecuteDelegateCommand = new DelegateCommand(Execute, CanExecute);

DelegateCommandObservesProperty = new DelegateCommand(Execute, CanExecute)
.ObservesProperty(() => IsEnabled);

DelegateCommandObservesCanExecute = new DelegateCommand(Execute)
.ObservesCanExecute(() => IsEnabled);

ExecuteGenericDelegateCommand = new DelegateCommand<string>(ExecuteGeneric)
.ObservesCanExecute(() => IsEnabled);
}

private void Execute()
{
UpdateText = $"Updated: {DateTime.Now}";
}

private void ExecuteGeneric(string parameter)
{
UpdateText = parameter;
}

private bool CanExecute()
{
return IsEnabled;
}
}
}

View部分:

头部引入命名空间,指定ViewModeLocator模式:

1
2
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"

接着是一个:

1
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"></StackPanel>

接着内部是一组控件,一个CheckBox四个Button一个 TextBlock。

1
CheckBox IsChecked="{Binding IsEnabled}"

复选框的勾选状态绑定到一个布尔型属性上。

1
Button Command="{Binding ExecuteDelegateCommand}"

普通命令绑定

1
Button Command="{Binding ExecuteGenericDelegateCommand}" CommandParameter="Passed Parameter"

带参数的 命令绑定

1
TextBlock Text="{Binding UpdateText}"

为TextBlock的Text属性绑定数据源

Binding语法 Property=”{Binding PropertyPath}”,PropertyPath就是VM

当为Command进行Binding的时候,还可以带参数,使用CommandParameter属性,上面的CommandParameter指定了一个字符串“Passed Parameter”,当然还可以为其Binding一个对象。

ViewModel部分:

set方法中的:

SetProperty(ref _isEnabled, value);
属性变更的通知,当视图状态更新后,会通知VM更改_isEnabled。

ExecuteDelegateCommand.RaiseCanExecuteChanged();
这段代码,则会通知ExecuteDelegateCommand的可执行状态更改了,让他重新获取下可执行状态,那他是怎么获取可执行状态的呢?我们看下这个Command:

ExecuteDelegateCommand = new DelegateCommand(Execute, CanExecute);
new 的时候,有两个参数,第一个是Action(无返回类型的方法)Execute(需要执行的方法),第二个是一个Func,就是一个返回布尔型的方法CanExecute来获取command的可执行状态,当上面通知他可执行状态变更后,他就会重新调用CanExecute方法来获取目前的可执行状态(也就是按钮的可按下状态),来看下这个方法:

1
2
3
4
private bool CanExecute()
{
return IsEnabled;
}

很简单,直接返回了IsEnabled,而他是跟视图的CheckBox的IsChecked绑定的,当然也可以返回_isEnabled,而我更倾向后面这个,Public那个是给外人用的,蛤蛤。

当然可执行状态,还有其他的更优雅的写法,也就不用写ExecuteDelegateCommand.RaiseCanExecuteChanged();了,具体代码如下:

1
2
3
4
DelegateCommandObservesProperty = new DelegateCommand(Execute, CanExecute)
.ObservesProperty(() => IsEnabled);
DelegateCommandObservesCanExecute = new DelegateCommand(Execute)
.ObservesCanExecute(() => IsEnabled);

下面这个是带参数的命令(command),他的回调函数需要一个string类型的参数,在new的时候要指定入参类型:

1
2
ExecuteGenericDelegateCommand = new DelegateCommand<string>(ExecuteGeneric)
.ObservesCanExecute(() => IsEnabled);

回调函数ExecuteGeneric:

1
2
3
4
private void ExecuteGeneric(string parameter)
{
UpdateText = parameter;
}

评论