LoginSignup
6
8

More than 5 years have passed since last update.

WinFormsのINotifyPropertyChangedを使ってみる

Last updated at Posted at 2018-08-01

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

BindingSourceを使用してnumericUpDownコントロールのValueにViewModelクラスをバインド、
ValueChangedイベントのタイミングで入力値を使用して、描画内容更新を実装したかったのですが、
ValueChangedイベントハンドラ内でViewModel参照しても値が更新されてねぇ!ってなったので、
値が変更されたら教えて~と思ってINotifyPropertyChanged使いました。(ながい

INotifyPropertyChanged

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

使い方

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

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8