WPF でコントロールにオブジェクトを Binding している場合、オブジェクトのプロパティが変更されたときにコントロールの表示も伴って更新されてほしいわけだが、残念ながら更新されない。
これは、更新されたことを通知する機構がオブジェクトに備わっていないからである。 このページではこれの対応策を示す。
コントロールにプロパティが変更されたことを通知するには、まずバインドするクラスに INotifyPropertyChanged インターフェースを実装しておく。
INotifyPropertyChanged を実装すると PropertyChanged イベントが追加されるので、これをコールするための下記のようなメソッドを作っておく。
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(name));
}
}
この引数 name には変更されたプロパティの名前を渡す。
そして変更を通知すべきプロパティ(表示を更新する必要のあるプロパティ)の set アクセサで次のようにコールする。
private string _userId;
public string UserId
{
get
{
return _userId;
}
set
{
_userId = value;
OnPropertyChanged("UserId");
}
}
これで UserId に値がセットされると、変更が通知されるようになる。
たとえば TreeView に階層構造のオブジェクトをバインドしているとする。
オブジェクトの中のコレクションを List<T> などで実装しているとこれらのコレクションに要素が追加もしくは削除されたとき、TreeView の表示が更新されない。 また、これはコレクションのプロパティから PropertyChanged を呼んでも同じである。
これを自動的に反映されるようにするにはコレクションに ObservableCollection<T> クラスを利用すればいい。
以上の実装例を示す。
public class TopLevel : System.ComponentModel.INotifyPropertyChanged
{
private string _userId;
public string UserId
{
get
{
return _userId;
}
set
{
_userId = value;
OnPropertyChanged("UserId");
}
}
public ObservableCollection<SecondLevel> SecondLevels { get; set; } }
#region INotifyPropertyChanged メンバー
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(name));
}
}
#endregion
}
Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。
好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。
詳しくは Web mixi で。