DependencyPropertyは、基本的にプリミティブな型やシンプルな型(intやstring、boolなど)、またはWPFがサポートする型に対して直接的に定義するのが一般的です。しかし、DependencyPropertyでクラスをプロパティとして使用したい場合もあります。その際には、クラスをDependencyPropertyの型として登録し、適切にプロパティ変更の通知が行えるようにします。
例:クラス型のDependencyPropertyを使用する
以下の例では、Personクラスをプロパティとして使用したいとします。この場合、Personオブジェクトを持つDependencyPropertyを定義できますが、Personクラスが変更通知をサポートするようにINotifyPropertyChangedを実装しておくと、内部プロパティの変更も検知できるようになります。
// 変更通知をサポートするPersonクラス
public class Person : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
次に、UserControlにPerson型のDependencyPropertyを定義します。
public partial class MyUserControl : UserControl
{
public static readonly DependencyProperty PersonProperty =
DependencyProperty.Register(
nameof(Person),
typeof(Person),
typeof(MyUserControl),
new PropertyMetadata(null, OnPersonChanged));
public Person Person
{
get => (Person)GetValue(PersonProperty);
set => SetValue(PersonProperty, value);
}
public MyUserControl()
{
InitializeComponent();
}
// Personプロパティが変更された時のコールバック
private static void OnPersonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as MyUserControl;
if (e.OldValue is Person oldPerson)
{
// 古いPersonの変更イベントを解除
oldPerson.PropertyChanged -= control.Person_PropertyChanged;
}
if (e.NewValue is Person newPerson)
{
// 新しいPersonの変更イベントを監視
newPerson.PropertyChanged += control.Person_PropertyChanged;
}
}
// Personのプロパティ変更が検知された時の処理
private void Person_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// ここでプロパティ変更に応じた処理を行うことができます
Console.WriteLine($"Property {e.PropertyName} changed in Person");
}
}
解説
クラス型の
DependencyPropertyを登録:PersonPropertyとしてDependencyPropertyを登録し、Personクラスをプロパティとして持たせています。
プロパティ変更のコールバック (
OnPersonChanged):DependencyPropertyの変更時に呼び出されるコールバックを設定し、新しいPersonオブジェクトに対してPropertyChangedイベントを購読します。
内部プロパティの変更を監視:
Personオブジェクト内でのプロパティ変更は、INotifyPropertyChangedによってPerson_PropertyChangedで監視できるため、内部のプロパティ(Nameなど)の変更にも応答できます。
このようにすることで、DependencyPropertyがクラス型のプロパティとして機能し、クラス内部のプロパティ変更も通知を受け取ることが可能になります。


コメント