Article directory
foreword
CommunityToolkit.Mvvm (hereinafter referred to as Toolkit) is the two most famous frameworks of WPF, one is Prism and the other is Toolkit.
Prism can see my Prism detailed explanation
Toolkit
Toolkit Official Documentation
Accelerate MVVM development process with CommunityToolkit.Mvvm
Nuget installation
easy to use
Toolkit simply rewrites our two commonly used methods,
one is SetProperty and the other is RelayCommand
SetProperty, notify update
public class MainViewModel:ObservableObject
{
private string _title;
public string Title
{
get => _title;
set => SetProperty(ref _title,value);
}
}
RealyCommand
public RelayCommand ButtonClickCommand {
get; set; }
public MainViewModel()
{
ButtonClickCommand = new RelayCommand(() => {
Debug.WriteLine("Hello World!"); });
}
Summary of 3 commands in MVVM mode [2]-RelayCommand
RealyCommand mainly has a CanExecute property. Whether the notification is clickable
CanExecute
Whether the notification button can be clicked (I feel a bit tasteless)
public class MainViewModel:ObservableObject
{
private string _title = "Hello world!";
public string Title
{
get => _title;
set => SetProperty(ref _title,value);
}
private bool _isEnable = false;
public bool IsEnable
{
get=> _isEnable;
set
{
SetProperty(ref _isEnable,value);
ButtonClickCommand.NotifyCanExecuteChanged();
}
}
public RelayCommand ButtonClickCommand {
get; set; }
public MainViewModel()
{
ButtonClickCommand = new RelayCommand(() => {
Title = "Value is changed"; },()=>IsEnable);
}
}
<Window.DataContext>
<viewModel:MainViewModel />
</Window.DataContext>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
<TextBox Text="{Binding Title}" Width="200"/>
<CheckBox Content="Is Enable" IsChecked="{Binding IsEnable}" />
<Separator Margin="5"/>
<Button Command="{Binding ButtonClickCommand}" Content="Click Me"/>
</StackPanel>
</Grid>
new features, code generator
Toolkit has added a generator function, which automatically completes the code for us.
ObservableProperty
The generated Public attribute conforms to the following characteristics
- private
- name=>Name
- _name=>Name
- m_name=>Name
The above three will automatically correspond to the public Name
NotifyCanExecuteChangedFor
Because we previously modified RelayCommand's CanExecute to be notified through the get set in the public, we can now use NotifyCanExecuteChangedFor to notify
[NotifyCanExecuteChangedFor(nameof(ButtonClickCommand))]
[ObservableProperty]
private bool _isEnable = false;
//等价于
private bool _isEnable = false;
public bool IsEnable
{
get=> _isEnable;
set
{
SetProperty(ref _isEnable,value);
ButtonClickCommand.NotifyCanExecuteChanged();
}
}
RelayCommand
RelayCommand gives a Void function, which will automatically generate a corresponding Command and initialize the Command
[RelayCommand]
public void ButtonClick()
{
}
//等价于
public RelayCommand ButtonClickCommand {
get; set; }
public MainViewModel()
{
ButtonClickCommand = new RelayCommand(() => {
Title = "Value is changed"; }, () => IsEnable);
}
Other functions
//将CanExecute绑定到IsEnable
[RelayCommand(CanExecute =nameof(IsEnable))]
public void ButtonClick()
{
}
///异步函数也可以,CanExecute会在异步函数结束之后变回去
[RelayCommand(CanExecute =nameof(IsEnable))]
public async Task ButtonClickAsync()
{
await Task.Delay(1000);
Title = "我被修改了";
}
Asynchronous function demo: pay attention to the color of the button
Correspondence
ButtonClickAsync、ButtonClick=>ButtonClickCommand
NotifyPropertyChangedFor
We hope that two attributes are strongly associated, such as Title and TestStr are strongly associated.
We want to be able to notify that another property has changed, such as Title notifies TestStr of changes
private string testStr = $"Title:{
Title}";
But writing like this will report an error, only static methods can be set
and then we can notify through NotifyPropertyChangedFor
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(TestStr))]
private string _title = "Hello world!";
public string TestStr => $"Title:{
Title}";