C# 使用 CommunityToolkit.Mvvm 套件更簡單實現屬性變更通知

在之前 C# Winform 屬性變更通知 INotifyPropertyChanged 示範 中有示範實作 INotifyPropertyChanged 介面,達到到資料綁定的功能。

不過其實在微軟的社群中有一款套件 CommunityToolkit.Mvvm ,能夠讓我們很方便的實現 MVVM (Model-View-ViewModel)架構,能夠使用更少的程式碼實作 INotifyPropertyChanging 。

註: CommunityToolkit.Mvvm 並沒有綁定 UI 框架,在 WinForms, WPF, WinUI 上都可以使用,只是本篇使用 WinForms 做示範。

安裝套件

先使用 NuGet 安裝 CommunityToolkit.Mvvm 套件,或是使用 .NET CLI 執行以下指令安裝
	
dotnet add package CommunityToolkit.Mvvm
    

該總下載次數超過 270 萬,平均每天有 2.8K 下載,算是非常高。最近更新是 3 周前(撰稿時間為 2023-11-17)

範例

建立一個 Settings 類別,繼承 ObservableObject ,放一個屬性 CanClickButton ,用來儲存按鈕可不可以被按下,下面是本套件最基本的使用方式:
    
public class Settings : ObservableObject
{
    private bool _canClickButton = true;

    public bool CanClickButton
    {
        get => _canClickButton;
        set => SetProperty(ref _canClickButton, value);
    }
}
    

接下來就只是綁定了,並不是新的內容。
動態產生兩個按鈕:button1, button2 ,button2 點擊時會改變 CanClickButton 狀態,然後讓 button1 的 Enabled 屬性綁定 CanClickButton ,這樣點擊 button2 改變 CanClickButton 時 button1 就會自動改變狀態變成啟用或是禁用了:
    
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        Settings settings = new Settings();


        var button1 = new Button
        {
            Text = "Button1",
            Location = new Point(10, 10),
        };
        button1.Click += (_, _) => { MessageBox.Show("Hello"); };
        button1.DataBindings.Add(nameof(Button.Enabled), settings, nameof(Settings.CanClickButton));
        this.Controls.Add(button1);

        var button2 = new Button
        {
            Text = "Button2",
            Location = new Point(10, 40),
        };
        button2.Click += (_, _) => settings.CanClickButton = !settings.CanClickButton;
        this.Controls.Add(button2);
    }
}

    

下面這一行是綁定的語法:
    
button1.DataBindings.Add(nameof(Button.Enabled), settings, nameof(Settings.CanClickButton));
    

也可以替換為追蹤繼承 ObservableObject 的 Settings 類別資料是否變更,然後判斷變更的屬性是不是我們在意的 CanClickButton ,然後更新 button 狀態。
    
settings.PropertyChanged += (sender, args) =>
{
    if (args.PropertyName != nameof(Settings.CanClickButton)) return;
    button.Enabled = settings.CanClickButton;
};
    



參考資料:
GitHub - CommunityToolkit/dotnet
Microsoft.Learn - Introduction to the MVVM Toolkit

留言