RelayCommand有4个成员
// 命令源触发命令后执行
void Execute(object? parameter);
// Execute内部调用会此方法,判断是否真的去执行
bool CanExecute(object? parameter);
// 通知命令源是否被禁用。在ViewModel中调用CanExecuteChanged?.Invoke(this, EventArgs.Empty)可以刷新绑定此命令的元素的启禁用状态;但一般不会调用,而是采用下一个成员void NotifyCanExecuteChanged()刷新命令源的启禁用状态。
// 此事件无需用户注册,WPF的命令机制在UI元素的Command与ViewModel的RelayCommand绑定时自动注册Wpf内部的事件处理程序。
event EventHandler? CanExecuteChanged;
// 通知命令源是否被禁用。是对CanExecuteChanged?.Invoke(this, EventArgs.Empty)的封装,完全等价。
void NotifyCanExecuteChanged();
Execute和CanExecute在UI线程上执行,如有耗时操作,请异步,否则卡UI
RelayCommand的构造方法如下:
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
execute:命令执行的操作
canExecute:命令是否可执行
object是指命令参数,无命令参数时值为null,有参数时,参数委托execute和canExecute若处理,需先进行类型转换后使用。
<StackPanel>
<Button Content="不带参数的命令" Command="{Binding CommandWithoutParam}" Margin="5" Background="Orange"/>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBox MinWidth="100" Name="txt"/>
<Button Content="带参数的命令" Command="{Binding CommandWithParam}" CommandParameter="{Binding Path=Text, ElementName=txt}" Margin="5 0 0 0" Background="Lime" />
</StackPanel>
</StackPanel>
public class MainViewModel:ObservableRecipient
{
/// <summary>
/// 不带参数的命令
/// </summary>
public RelayCommand CommandWithoutParam { get; }
/// <summary>
/// 带参数的命令
/// </summary>
public RelayCommand CommandWithParam { get; }
public MainViewModel()
{
CommandWithoutParam = new RelayCommand((obj) =>
{
MessageBox.Show("Hello Mvvm CommandWithoutParams");
}, (obj) => { return DateTime.Now.Second % 10 == 0 || DateTime.Now.Second % 10 == 1 || DateTime.Now.Second % 10 == 2 || DateTime.Now.Second % 10 == 3 || DateTime.Now.Second % 10 == 4; });
CommandWithParam = new RelayCommand((obj) =>
{
MessageBox.Show("Command Parameter :" + obj.ToString());
});
}
}
- 泛型命令与非泛型命令的区别
- 无参,单参,多参命令
- Execute在UI线程执行,所以不可耗时操作
- CanExecuteChanged在UI线程执行,也不可有耗时操作。
- 如何通知UI命令发生了变化。