c#でxamlのようなパスバインディングを作成する方法
-
02-10-2019 - |
質問
XAML {Binding}コンストラクトは、すべてのプロパティ変更された問題を自動的に処理するため、非常に便利です。 .NETデータ構造を介してオブジェクトへのパスを渡すと、すべてが自動的に更新されます。
同じものをC#で使用したいと思います。別のプロパティの価値から派生したプロパティを持ちたいと思います。例
class Foo
{
public Bar Bar = new Bar();
public string ItGetter
{
get
{
return Bar.Baz.It;
}
}
}
class Bar
{
public Baz Baz = new Baz();
}
class Baz
{
public string It { get { return "You got It!"; } }
}
FooでItgetterを呼び出すと、BazからIT値が表示されます。これは正常に機能しますが、無効ではないことを除いて、変更された場合、Itgetterの変更通知はありません。さらに、foo.barまたはbar.bazの参照が変更された場合、変更が変更されない場合もあります。
プロパティに適切なiChangEnotifyコードを追加できますが、私の質問は次のとおりです。ITGetterプロパティをコーディングして、パス内の参照のいずれかまたはIT値が変更されたときにプロパティ変更イベントを呼び出すようにするにはどうすればよいですか?パス内のすべてのアイテムでプロパティ変更されたイベントを手動でセットアップする必要がないことを願っています。
助けてくれてありがとう!
エリック
解決
あなたは見ることができます 依存特性. 。これらを使用すると、メタデータのスタックと詳細なバリュー解像度システムがバックされているWPFプロパティシステムのプロパティを定義できます。
あなたにとって重要なことは、彼らがあなたがプロパティ変更されたイベントに登録することを可能にすることを可能にし、彼らはあなたが他のものに依存する価値を作ることを可能にすることです。
そのような他の良いアートサイドがあります ジョシュ・スミスによる「依存関係の分離プロパティ」 と クリスチャンモーザーによる「依存関係のプロパティ」
あなたも読みたいかもしれません 依存関係プロパティコールバックと検証
他のヒント
サイモンが述べたように、依存関係プロパティを使用して、私が探していたものを行う完全なコードは次のとおりです。
// This class exists to encapsulate the INotifyPropertyChanged requirements
public class ChangeNotifyBase : DependencyObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public class Foo : ChangeNotifyBase
{
public Foo()
{
Bar = new Bar();
var binding = new Binding("Bar.Baz.It");
binding.Source = this;
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(this, ItGetterProperty, binding);
}
/// <summary>
/// The ItGetter dependency property.
/// </summary>
public bool ItGetter
{
get { return (bool)GetValue(ItGetterProperty); }
set { SetValue(ItGetterProperty, value); }
}
public static readonly DependencyProperty ItGetterProperty =
DependencyProperty.Register("ItGetter", typeof(bool), typeof(Foo));
// Must do the OnPropertyChanged to notify the dependency machinery of changes.
private Bar _bar;
public Bar Bar { get { return _bar; } set { _bar = value; OnPropertyChanged("Bar"); } }
}
public class Bar : ChangeNotifyBase
{
public Bar()
{
Baz = new Baz();
}
private Baz _baz;
public Baz Baz { get { return _baz; } set { _baz = value; OnPropertyChanged("Baz"); } }
}
public class Baz : ChangeNotifyBase
{
private bool _it;
public bool It { get { return _it; } set { _it = value; OnPropertyChanged("It"); } }
}
Itgetterでイベントに登録するようになった場合、これらのことが変更された場合に通知が表示されます。
オブジェクト参照(foo.barまたはbar.baz)をnullに設定すると、iTgetterの値はfalseに変更されます。