C# Language
INotifyPropertyChangedインターフェイス
サーチ…
備考
INotifyPropertyChanged
インタフェースは、クラスがそのプロパティに対して行われた変更を報告する必要がある場合に必要INotifyPropertyChanged
。インタフェースは、単一のイベントPropertyChanged
定義します。
XAMLバインディングを使用すると、 PropertyChanged
イベントが自動的に配線されるため、ビューモデルまたはデータコンテキストクラスでINotifyPropertyChangedインターフェイスを実装するだけで、XAMLバインディングを使用できます。
C#6でINotifyPropertyChangedを実装する
INotifyPropertyChange
の実装では、インターフェイスでプロパティ名を文字列として指定する必要があるため、エラーが発生する可能性があります。実装をより堅固にするために、属性CallerMemberName
を使用することができます。
class C : INotifyPropertyChanged
{
// backing field
int offset;
// property
public int Offset
{
get
{
return offset;
}
set
{
if (offset == value)
return;
offset = value;
RaisePropertyChanged();
}
}
// helper method for raising PropertyChanged event
void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// interface implemetation
public event PropertyChangedEventHandler PropertyChanged;
}
INotifyPropertyChanged
実装するクラスがいくつかある場合は、インターフェイスの実装をリファクタリングし、ヘルパーメソッドを共通の基本クラスにリファクタリングすると便利です。
class NotifyPropertyChangedImpl : INotifyPropertyChanged
{
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// interface implemetation
public event PropertyChangedEventHandler PropertyChanged;
}
class C : NotifyPropertyChangedImpl
{
int offset;
public int Offset
{
get { return offset; }
set { if (offset != value) { offset = value; RaisePropertyChanged(); } }
}
}
INotifyPropertyChanged(汎用設定メソッドを使用)
以下のNotifyPropertyChangedBase
クラスは、任意の派生型から呼び出すことができる汎用のSetメソッドを定義しています。
public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public event PropertyChangedEventHandler PropertyChanged;
public virtual bool Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(field, value))
return false;
storage = value;
RaisePropertyChanged(propertyName);
return true;
}
}
この汎用的なSetメソッドを使用するには、NotifyPropertyChangedBaseから派生したクラスを作成するだけです。
public class SomeViewModel : NotifyPropertyChangedBase
{
private string _foo;
private int _bar;
public string Foo
{
get { return _foo; }
set { Set(ref _foo, value); }
}
public int Bar
{
get { return _bar; }
set { Set(ref _bar, value); }
}
}
上記のように、 Set(ref _fieldName, value);
呼び出すことができますSet(ref _fieldName, value);
プロパティのセッターで、必要に応じて自動的にPropertyChangedイベントを発生させます。
プロパティの変更を処理する必要がある別のクラスからPropertyChangedイベントに登録できます。
public class SomeListener
{
public SomeListener()
{
_vm = new SomeViewModel();
_vm.PropertyChanged += OnViewModelPropertyChanged;
}
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine($"Property {e.PropertyName} was changed.");
}
private readonly SomeViewModel _vm;
}