說明
CommunityToolkit.Mvvm8.1最令人驚喜的是它提供的源生成器功能,它極大簡化我們的mvvm程式碼
我們透過標記一個屬性就可以實現某個功能,這個很方便快捷,推薦
常用標記總結
1.繼承ObservableObject 並且類標記是分部類partial
2.私有變數標記屬性 [ObservableProperty]
3.NotifyCanExecuteChangedFor 通知依賴命令
NotifyPropertyChangedFor 通知依賴屬性
4.RelayCommand 定義命令
5.OnPropertyChanged 手動通知屬性更新
6.ButtonClickCommand.NotifyCanExecuteChanged() 手動通知命令更新
7.OnLastNameChanging OnLastNameChanged 某個屬性改變
8.OnPropertyChanged 所有屬性改變
定義viewmodel
定義vm時,請使用分部類,並且繼承ObservableObject
public partial class DataViewModel2 : ObservableObject
{
}
/*
[ObservableProperty]標記後,會自動生成屬性(大寫命名),例如:下面會自動生成Title
注意:這個私有變數命名:必須是小寫開頭,或者下劃線,或者m_
*/
[ObservableProperty]
private string title = "hello";
//public string Title
//{
// get
// {
// return title;
// }
// set
// {
// //title = value;
// //PropertyChanged?.Invoke( this , new PropertyChangedEventArgs( "Name" ) );
// //SetProperty 相當與設定值,並且PropertyChanged通知呼叫
// SetProperty( ref title , value );
// }
//}
public string Caption
{
get
{
return string.Format( "Title:{0}-{1}" , Title , LastName );
}
}
[ObservableProperty]
[NotifyPropertyChangedFor( nameof( Caption ) )]
private string lastName = "abc";
/*
[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
NotifyCanExecuteChangedFor是通知依賴命令(觸發命令),相當於set中ButtonClickCommand.NotifyCanExecuteChanged();
*/
[ObservableProperty]
[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
private bool isEnabled = false;
//public bool IsEnabled
//{
// get => isEnabled;
// set
// {
// SetProperty( ref isEnabled , value );
// //通知命令 已經改變
// ButtonClickCommand.NotifyCanExecuteChanged();
// }
//}
//partial void OnIsEnabledChanged ( bool value )
//{
// //如果上面的[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]不寫,可以這裡手動通知更新
// //ButtonClickCommand.NotifyCanExecuteChanged();
//}
/*
RelayCommand是定義命令,自動生成的命令名是方法名+Command,並且初始化
例如:下面的會自動生成ButtonClickCommand
CanExecute是指定一個判斷方法,判斷是否可用
*/
[RelayCommand( CanExecute = nameof( CanButton ) )]
void ButtonClick ()
{
//點選按鈕,修改標題
Title = "hello(改)";
}
bool CanButton ()
{
return IsEnabled;
}
//public RelayCommand ButtonClickCommand
//{
// get;
//}
[RelayCommand]
void ButtonClickPar ( double val )
{
Title = $"hello(改):{val}";
}
//public RelayCommand<double> ButtonClickParCommand
//{
// get;
//}
[RelayCommand]
async Task AsyncButtonClick ()
{
await Task.Delay( 4800 );
Title = "hello(Task改)";
}
[RelayCommand]
async Task AsyncButtonParClick ( double val )
{
await Task.Delay( 4800 );
Title = $"hello(Task改):{val}";
}
<!--
特別說明:非同步命令會自動控制控制元件的可見性,並且提供一個IsRunning屬性可以判斷非同步是否完成
-->
<Button Width="100"
Height="30"
Command="{Binding AsyncButtonClickCommand}"
Content="非同步" />
<TextBlock HorizontalAlignment="Center"
FontSize="20"
FontStyle="Italic"
FontWeight="Bold"
Foreground="Green"
Text="loading......"
Visibility="{Binding AsyncButtonClickCommand.IsRunning, Converter={StaticResource myboolconvert}}" />
/*
還可以實現2個方法:OnLastNameChanging OnLastNameChanged (注意2個方法只可以實現其中一個,或者都不實現(不能同時2個))
*/
//partial void OnLastNameChanging ( string value )
//{
// Debug.WriteLine( value );
//}
partial void OnLastNameChanged ( string value )
{
// 可以做一些其它事情 例如:屬性改變後,訊息通知某某某
Debug.WriteLine( value );
//說明:如果上面[NotifyPropertyChangedFor( nameof( Caption ) )]不寫,可以這裡手動通知屬性更新
//OnPropertyChanged( nameof( Caption ) );
}
/// <summary>
/// 所有屬性改變
/// </summary>
/// <param name="e"></param>
protected override void OnPropertyChanged ( PropertyChangedEventArgs e )
{
base.OnPropertyChanged( e );
// 可以獲取到是哪個屬性改變了
var _proname = e.PropertyName;
}
完整程式碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
/*
這裡演示自動生成屬性和命令
1.繼承ObservableObject 並且類標記是分部類partial
2.私有變數標記屬性 [ObservableProperty]
3.NotifyCanExecuteChangedFor 通知依賴命令
NotifyPropertyChangedFor 通知依賴屬性
4.RelayCommand 定義命令
5.OnPropertyChanged 手動通知屬性更新
6.ButtonClickCommand.NotifyCanExecuteChanged() 手動通知命令更新
7.OnLastNameChanging OnLastNameChanged 某個屬性改變
8.OnPropertyChanged 所有屬性改變
*/
namespace WpfDemoNet6.Demo
{
public partial class DataViewModel2 : ObservableObject
{
/*
[ObservableProperty]標記後,會自動生成屬性(大寫命名),例如:下面會自動生成Title
注意:這個私有變數命名:必須是小寫開頭,或者下劃線,或者m_
*/
/*
NotifyPropertyChangedFor 通知依賴屬性Caption
*/
[ObservableProperty]
[NotifyPropertyChangedFor( nameof( Caption ) )]
private string title = "hello";
//public string Title
//{
// get
// {
// return title;
// }
// set
// {
// //title = value;
// //PropertyChanged?.Invoke( this , new PropertyChangedEventArgs( "Name" ) );
// //SetProperty 相當與設定值,並且PropertyChanged通知呼叫
// SetProperty( ref title , value );
// }
//}
/*
[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
NotifyCanExecuteChangedFor是通知依賴命令(觸發命令),相當於set中ButtonClickCommand.NotifyCanExecuteChanged();
*/
[ObservableProperty]
[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]
private bool isEnabled = false;
//public bool IsEnabled
//{
// get => isEnabled;
// set
// {
// SetProperty( ref isEnabled , value );
// //通知命令 已經改變
// ButtonClickCommand.NotifyCanExecuteChanged();
// }
//}
//partial void OnIsEnabledChanged ( bool value )
//{
// //如果上面的[NotifyCanExecuteChangedFor( nameof( ButtonClickCommand ) )]不寫,可以這裡手動通知更新
// //ButtonClickCommand.NotifyCanExecuteChanged();
//}
/*
RelayCommand是定義命令,自動生成的命令名是方法名+Command,並且初始化
例如:下面的會自動生成ButtonClickCommand
CanExecute是指定一個判斷方法,判斷是否可用
*/
[RelayCommand( CanExecute = nameof( CanButton ) )]
void ButtonClick ()
{
//點選按鈕,修改標題
Title = "hello(改)";
}
bool CanButton ()
{
return IsEnabled;
}
//public RelayCommand ButtonClickCommand
//{
// get;
//}
public DataViewModel2 ()
{
//RelayCommand的第一個引數是命令呼叫語句
// 第2個引數(可選)是否允許使用
//ButtonClickCommand = new RelayCommand( () =>
//{
// //點選按鈕,修改標題
// Title = "hello(改)";
//} , () =>
//{
// return IsEnabled;
//} );
//ButtonClickParCommand = new RelayCommand<double>( ( double val ) =>
//{
// Title = $"hello(改):{val}";
//} );
}
[RelayCommand]
void ButtonClickPar ( double val )
{
Title = $"hello(改):{val}";
}
//public RelayCommand<double> ButtonClickParCommand
//{
// get;
//}
public string Caption
{
get
{
return string.Format( "Title:{0}-{1}" , Title , LastName );
}
}
[ObservableProperty]
[NotifyPropertyChangedFor( nameof( Caption ) )]
private string lastName = "abc";
/*
還可以實現2個方法:OnLastNameChanging OnLastNameChanged (注意2個方法只可以實現其中一個,或者都不實現(不能同時2個))
*/
//partial void OnLastNameChanging ( string value )
//{
// Debug.WriteLine( value );
//}
partial void OnLastNameChanged ( string value )
{
// 可以做一些其它事情 例如:屬性改變後,訊息通知某某某
Debug.WriteLine( value );
//說明:如果上面[NotifyPropertyChangedFor( nameof( Caption ) )]不寫,可以這裡手動通知屬性更新
//OnPropertyChanged( nameof( Caption ) );
}
/// <summary>
/// 所有屬性改變
/// </summary>
/// <param name="e"></param>
protected override void OnPropertyChanged ( PropertyChangedEventArgs e )
{
base.OnPropertyChanged( e );
// 可以獲取到是哪個屬性改變了
var _proname = e.PropertyName;
}
}
}