Edited at

WinFormsのINotifyPropertyChangedを使ってみる

More than 1 year has passed since last update.

初投稿してみた ありふれた情報です

BindingSourceを使用してnumericUpDownコントロールのValueにViewModelクラスをバインド、

ValueChangedイベントのタイミングで入力値を使用して、描画内容更新を実装したかったのですが、

ValueChangedイベントハンドラ内でViewModel参照しても値が更新されてねぇ!ってなったので、

値が変更されたら教えて~と思ってINotifyPropertyChanged使いました。(ながい


INotifyPropertyChanged

VM側からUIに変更通知を行いたいときにこのインターフェースを使用する。

https://msdn.microsoft.com/ja-jp/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx


使い方

INotifyProperChangedを継承したViewModelクラスを作成する。

PropertyChangedイベントを忘れずに実装する。


PersonViewModel.cs

    public class PersonViewModel : INotifyPropertyChanged

{
private Person _person;

public event PropertyChangedEventHandler PropertyChanged

public string Name
{
get { return _person.Name; }
set { _person.Name = value; }
}

public int Age
{
get { return _person.Age; }
set { _person.Age = value; }
}
}


UI側のBindingSourceにVMを設定する。

適当にPropertyChangedイベントにハンドラを設定する。


MainForm.cs

    public partial class MainForm : Form

{
private MainViewModel _vm;

public MainForm()
{
InitializeComponent();

_vm = new PersonViewModel();

bindingSource.DataSource = _vm;

_vm.PropertyChanged += VmOnPropertyChanged;
}
}


これだけだとVMが変更されてもイベントは上がってきません。

VM側で値が変更されたときにイベントを上げてあげる必要があるのです。

(めんどくさい)

イベント上げてくれるようにPersonViewModelを変更する。

※_person null かもよ!って言われたのでさり気なくコンストラクタで初期化してます。


PersonViewModel.cs

    public class PersonViewModel : INotifyPropertyChanged

{
private Person _person;

public event PropertyChangedEventHandler PropertyChanged;

public PersonViewModel( Person person )
{
_person = person;
}

public string Name
{
get { return _person.Name; }
set
{
if( _person.Name == value )
return;

_person.Name = value;
NotifyPropertyChanged();
}
}

public int Age
{
get { return _person.Age; }
set
{
if( _person.Age == value )
return;

_person.Age = value;
NotifyPropertyChanged();
}
}

private void NotifyPropertyChanged( [CallerMemberName] string propertyName = "" )
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
}
}


参考

https://blog.okazuki.jp/entry/2015/05/09/124333

https://qiita.com/ledsun/items/6f4ef754e5ae2507e531