Come creare XAML come attacchi di percorso in C #
-
02-10-2019 - |
Domanda
Il XAML {Binding} costrutto è molto utile perché gestisce tutti i problemi PropertyChanged automaticamente. E 'davvero impressionante quando si passi il percorso di un oggetto, attraverso strutture di dati .NET, e tutto viene aggiornato automaticamente per voi.
Vorrei utilizzare la stessa cosa in C #. Mi piacerebbe avere una proprietà che è derivato dal valore di un'altra proprietà. Esempio
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!"; } }
}
Se ItGetter chiamata su un Foo, si ottiene il valore che da Baz. Questo funziona bene, tranne che non è inficiata -. Cioè, se è cambiato, non ci sarebbero le notifiche di modifica sul ItGetter. Inoltre, se i riferimenti foo.bar o Bar.Baz sono cambiati, si potrebbe anche non ottenere noficiations cambiamento.
posso aggiungere il codice IChangeNotify appropriata sulle proprietà, ma la mia domanda è: come faccio a codificare la proprietà ItGetter tale che chiamerà il suo evento PropertyChanged quando uno dei riferimenti nel percorso, o la variazione del valore di It? Spero di non dover proprietà di installazione manualmente gli eventi cambiato su tutte le voci del percorso ....
Grazie per qualsiasi aiuto!
Eric
Soluzione
Si potrebbe dare un'occhiata al proprietà dipendenza . Essi consentono di definire le proprietà del sistema di proprietà WPF che sono sostenuta con pile di metadati e un articolato sistema Risoluzione del valore.
È importante sottolineare che per voi permettono permettono di registrare per la proprietà cambiato eventi, e permettono di effettuare i valori dipendenti da altre cose.
Ci sono alcuni altri buoni artcile intorno come 'Demystifying dipendenza proprieta di Josh Smith e 'proprietà di dipendenza' da Christian Mosers
Si potrebbe anche voler leggere proprietà di dipendenza Callback e convalida
Altri suggerimenti
Ecco il codice completo che fa quello che stavo cercando, utilizzando le proprietà di dipendenza, come detto Simon:
// 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"); } }
}
Se ora la registrazione per eventi in ItGetter, si otterrà una notifica se una qualsiasi di queste cose cambiano: Baz.It Foo.Bar (cioè, modificare il riferimento) Bar.Baz " "
Se si imposta su dei riferimenti agli oggetti (foo.bar o Bar.Baz) a nullo, il valore di ItGetter cambia false.