为什么在 ICommand 中需要 getter 和 setter?
Why do I need getters and setters in ICommand?
C#/MVVM 的新手,这对我来说没有意义?
这是我对继承自 ICommand 的 RelayCommand 的实现:
internal class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action _execute;
public event EventHandler CanExecuteChanged = (sender, e) => {};
public RelayCommand(Action execute) : this(execute, null){ }
public RelayCommand(Action execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => (_canExecute == null) ? true : _canExecute(parameter);
public void Execute(object parameter) => _execute();
}
我通过测试发现我不能只这样做:
public RelayCommand TestCommand;
我必须这样做:
public RelayCommand TestCommand { get; set; }
否则在构造函数中声明命令如下:
TestCommand = new RelayCommand(TestCommandFunction);
public void TestCommandFunction(){}
行不通。为什么会这样?
绑定通常不适用于字段。大多数绑定基于 ComponentModel PropertyDescriptor 模型,该模型适用于属性。这会启用通知、验证,并且 none 可以与字段一起使用。
所以是的,你需要属性。
您可以在构造函数中初始化它们,或者一种常见的模式是使用具有支持字段和表达式主体的延迟加载样式语法 属性
private RelayCommand _testCommand;
public RelayCommand TestCommand => _testCommand ?? (_testCommand = new RelayCommand(...));
C#/MVVM 的新手,这对我来说没有意义?
这是我对继承自 ICommand 的 RelayCommand 的实现:
internal class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action _execute;
public event EventHandler CanExecuteChanged = (sender, e) => {};
public RelayCommand(Action execute) : this(execute, null){ }
public RelayCommand(Action execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => (_canExecute == null) ? true : _canExecute(parameter);
public void Execute(object parameter) => _execute();
}
我通过测试发现我不能只这样做:
public RelayCommand TestCommand;
我必须这样做:
public RelayCommand TestCommand { get; set; }
否则在构造函数中声明命令如下:
TestCommand = new RelayCommand(TestCommandFunction);
public void TestCommandFunction(){}
行不通。为什么会这样?
绑定通常不适用于字段。大多数绑定基于 ComponentModel PropertyDescriptor 模型,该模型适用于属性。这会启用通知、验证,并且 none 可以与字段一起使用。
所以是的,你需要属性。
您可以在构造函数中初始化它们,或者一种常见的模式是使用具有支持字段和表达式主体的延迟加载样式语法 属性
private RelayCommand _testCommand;
public RelayCommand TestCommand => _testCommand ?? (_testCommand = new RelayCommand(...));