Cómo crear XAML como fijaciones de trayectoria en C #
-
02-10-2019 - |
Pregunta
El XAML {Binding} constructo es muy práctico, ya que se encarga de todos los asuntos PropertyChanged automáticamente. Es realmente impresionante cuando se pasa una ruta de acceso a un objeto, a través de las estructuras de datos .NET, y todo se actualiza automáticamente.
Me gustaría usar la misma cosa en C #. Me gustaría tener una propiedad que se deriva del valor de otra propiedad. Ejemplo
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!"; } }
}
Si llama ItGetter en un Foo, se obtiene el valor es de Baz. Esto funciona bien, excepto que no se invalida -. Es decir, si se cambia, no habría notificaciones de cambio en la ItGetter. Por otra parte, si se cambian las referencias foo.bar o Bar.Baz, usted también no obtener noficiations cambio.
Me puede añadir el código IChangeNotify apropiada sobre las propiedades, pero mi pregunta es: ¿Cómo codificar los ItGetter propiedad tal que se llamará su caso PropertyChanged cuando cualquiera de las referencias en el camino, o el cambio de valor de TI? Estoy esperando que no tengo a la propiedad de configuración de eventos cambian manualmente en todos los elementos de la ruta ....
Gracias por cualquier ayuda!
Eric
Solución
Se puede echar un vistazo a propiedades dependencia . Ellos le permiten definir las propiedades en el sistema de propiedades de WPF que se mueve hacia atrás con pilas de metadatos y un sistema detallado Resolución del valor.
Es importante para usted que permiten que le permiten registrar los eventos de propiedad cambiado, y que le permiten hacer los valores que dependen de otras cosas.
Hay alguna otra artcile bien a su alrededor, como 'Desmitificando la dependencia propiedades de Josh Smith y 'propiedades de dependencia' por Mosers cristianos
También puede ser que desee leer propiedades de dependencia devoluciones de llamada y validación
Otros consejos
Este es el código completo que hace lo que yo estaba buscando, utilizando propiedades de dependencia, como se ha mencionado Simón:
// 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"); } }
}
Si ahora se registra para eventos en ItGetter, usted recibirá una notificación si cualquiera de estas cosas cambian: Baz.It Foo.Bar (es decir, cambiar la referencia) Bar.Baz " "
Si se establece en las referencias a objetos (foo.bar o Bar.Baz) a nulo, el valor de ItGetter cambia a falso.