編集可能な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をシンプルに記述する手法も掲載しています。
0 件のコメント:
コメントを投稿