2018-05-12 (土)
[C#] INotifyPropertyChangedを楽に実装し、ReSharperのTemplateも作る
BindableBaseという基底クラスを用意し、継承して簡単に使用します。
ReSharperのテンプレート(スニペット)も用意して、記述も楽にします。
環境
- Windows 10 Pro 64bit 1709
- Visual Studio Community 2017 15.5.7
- .NET Framework 4.6.1
- C# 7.0
- ReSharper 2018.1
結果
実装
WPFで実装したサンプルソースはこちら
https://github.com/dokeep/csharp-bindablebase
BindableBase.cs
INotifyPropertyChanged
を実装した基底クラスを用意します。
public class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
return SetProperty(ref field, value, null, propertyName);
}
protected virtual bool SetProperty<T>(ref T field, T value, Action onChanged, [CallerMemberName]string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Sample.cs
実際に使用するクラスを作ります。以下の(例1)
と(例2)
は使い分けます。
public class Sample : BindableBase
{
public int Age
{
get => _age;
set => SetProperty(ref _age, value);
}
private int _age;
public string Name
{
get => _name;
// (例1) PropertyChangedが "Name" -> "FullName" の順に発生する例
set
{
if (SetProperty(ref _name, value) OnPropertyChanged(nameof(FullName)));
}
// (例2) PropertyChangedが "FullName" -> "Name" の順に発生する例
set => SetProperty(ref _name, value, () => OnPropertyChanged(nameof(FullName)));
}
private string _name;
public string FullName => $"Sample {Name}";
}
ReSharperのTemplateを作成
以下の3つのテンプレートをExportしたファイルはこちら。Importできます。
https://github.com/dokeep/csharp-bindablebase/blob/master/CsBindableBase/ReSharper/BindableBase.DotSettings
作成手順
メニューからReSharper
-> Tools
-> Templates Explorer...
を開きます。
New Template
ボタンで以下の3つのテンプレートを作成します。
その後に3つのテンプレートを選択して、New Category...
ボタンでBindableBase
というカテゴリを付けておきます。
ppa
public $TYPE$ $PROPERTY$
{
get => _$FIELD$;
set => SetProperty(ref _$FIELD$, value, () => $ACTION$);
}
private $TYPE$ _$FIELD$;
ppf
public $TYPE$ $PROPERTY$
{
get => _$FIELD$;
set
{
if (SetProperty(ref _$FIELD$, value))
{
$ACTION$
}
}
}
private $TYPE$ _$FIELD$;
ppp
public $TYPE$ $PROPERTY$
{
get => _$FIELD$;
set => SetProperty(ref _$FIELD$, value);
}
private $TYPE$ _$FIELD$;
感謝
関連記事
新着記事