跟着做的第一个MVVM项目, 学到一点基础的东西, 记下来; 有些用词不准确
假设我们要做一个页面, 通过按钮来控制上方文本框的文字, 通过勾选框来控制按钮的激活状态⬇️
一般流程
需要3个属性, 2个私有属性, 1个RelayCommand属性代表按钮点击后事件, 并配有相应的getter/setter
文本框的内容title
private string _title = "Hello World!";
public string Title
{
get => _title;
set { SetProperty(ref _title, value); }
}
按钮的激活状态isEnabled
private bool _isEnabled;
public bool IsEnabled
{
get => _isEnabled;
set
{
SetProperty(ref _isEnabled, value);
ButtonClickCommand.NotifyCanExecuteChanged();
}
}
按钮点击事件处理ButtonClickCommand
在类构造器里创建RelayCommand对象, 指定其Execute和CanExecute参数(注意lambda的使用)
public RelayCommand ButtonClickCommand { get; }
public MainWindowViewModel()
{
ButtonClickCommand = new RelayCommand(() => Title = "Hooray!!", () => IsEnabled);
}
然后在xaml文件里绑定这些值就行了
生成器
MVVMToolkit提供了生成器的功能, 通过标签的方式简化代码, 省去了一些重复格式的代码i.e.属性方法, 同时也能保证后台与前端的数据同步变化
两个私有属性
添加标签ObservableProperty
, 编译时会自动生成公共属性Title
以及方法
[ObservableProperty]
private string _title = "Hello World!";
同理, 这样会生成IsEnabled
⚠️ 注意上面写isEnabled的时候, 用到了一个NotifyCanExecuteChanged
的方法, 是用来提醒按钮事件的; 使用生成器后, 我们需要标签NotifyCanExecuteChangedFor
来保证这一行的功能
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ButtonClickCommand))]
private bool _isEnabled;
按钮事件
当我们有复数个按钮的事件需要处理时, 反复指定RelayCommand是不效率的(坏文明
同样可以用生成器简化操作, 不需要单独指定以及构造器⬇️
⭐因为我们不在构造器里指定按钮事件了, 所以在这里使用生成器时, 注意把漏掉的都补上
⭐RelayCommand标签将ButtonClick自动识别为一个RelayCommand属性(对象, 反正是那个意思)
⭐传入一个CanExecute参数(Func<bool>), 本来写的是一个lambda式返回了IsEnabled值, 但是这里不能这样写
⭐nameof
的作用是将方法名字符串化, 不能传入lambda
[RelayCommand(CanExecute = nameof(canButtonClick))]
private async Task ButtonClick()
{
// 为了这个延迟效果才用了Task类型
// ButtonClick执行时会先停1s, 同时按钮灰掉, 然后才会enabled和变化Title
await Task.Delay(1000);
Title = "Hooray!!";
}
// 我觉得这里的逻辑和之前的lambda格式是一样的, 只是给了一个名字, 作为CanExecute参数
private bool canButtonClick() => IsEnabled;
标签:MVVMToolkit,C#,isEnabled,Title,生成器,RelayCommand,private,按钮,WPF
From: https://www.cnblogs.com/Akira300000/p/18101142