MVVMなWPFでDataGridの内容変更をキャッチする

2019/11/11

C# WPF

アイキャッチ

編集可能なDataGridでユーザが編集したら、内容を即座にキャッチしたい事がよくあります。

内容が変更されたらXMLファイルに保存するとか、内容をチェックするとか使い道は色々あります。

MVVMなWPFアプリでReactivePropertyを使えばTextBoxなどはSubscribeで簡単に実現可能ですが、独自Classのデータ群をDataGridのItemsSourceへBindingした場合などの手法が分からず、

ReactivePropertySlim<List<MyClass>>なんて変数を作ってSubscribeでキャッチできるだろうか?などを試みましたが、あえなく撃沈...

TwitterでつぶやいたらReactivePropertyならこの人しかいないと私が思っている「かずき」さんから有り難いアドバイスを頂きました。

大雑把に言うと

ObserveElementPropertyChangedを使う。

MyClassのメンバーのsetにはSetPropertyを使う。

今回も最低限度必用な記述だけを掲載しますが、全貌は下記リンクを参照してください。

XAML

<DataGrid ItemsSource="{Binding Member}"/>

ViewModel

変数宣言

public ObservableCollection Member { get; } = new ObservableCollection();

コンストラクタ

コレクションの中身が変更されたか否かを監視する拡張メソッドが「ObserveElementPropertyChanged」です。

そして中身が変更されたら「Change」メソッドが実行されます。

Member.ObserveElementPropertyChanged().Subscribe(Changed).AddTo(Disposable);

内容変更で呼ばれるメソッド

private void Changed(SenderEventArgsPair pair)
{
    MessageBox.Show("Changed");
}

Classを追加

public class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected bool SetProperty(ref T field, T value, [CallerMemberName]string propertyName = null)
    {
        if (EqualityComparer.Default.Equals(field, value)) { return false; }
        field = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        return true;
    }
}

表示するデータ群のClass

public class People : BindableBase
{
    private string _Name;
    public string Name
    {
        get { return _Name; }
        set { SetProperty(ref _Name, value); }
    }
}

GitHubにはついでにプロパティのset getをシンプルに記述する手法も掲載しています。

自己紹介

自分の写真



新潟県のとある企業で働いてます。
【できる事】
電子回路設計
基板パターン設計
マイコンプログラム
C#(WinForms WPF)を使ったWindowsアプリケーション作成
PLCラダー
自動化装置アドバイザー
にほんブログ村 IT技術ブログ ソフトウェアへ

カテゴリ

このブログを検索

QooQ