programacion herramientas diseñador c# .net data-binding poco system.componentmodel

diseñador - herramientas de windows forms c#



Propiedades de enlace de datos POCO (6)

¿Hay algún marco de enlace de datos (BCL o de otro tipo) que permita el enlace entre dos propiedades CLR que implementen INotifyPropertyChanged y INotifyCollectionChanged ? Parece que debería ser posible hacer algo como esto:

var binding = new Binding(); binding.Source = someSourceObject; binding.SourcePath = "Customer.Name"; binding.Target = someTargetObject; binding.TargetPath = "Client.Name"; BindingManager.Bind(binding);

Donde someSourceObject y someTargetObject son solo POCOs que implementan INotifyPropertyChanged . Sin embargo, no tengo conocimiento de ningún soporte de BCL para esto, y no estoy seguro de si hay marcos existentes que lo permitan.

ACTUALIZACIÓN : Dado que no hay una biblioteca disponible, me he comprometido a escribir la mía. Está disponible here .

Gracias


Escribí here para llenar el vacío.


Escribí un pequeño proyecto Bind con soporte completo para el enlace entre propiedades neasted y acciones de enlace asíncronas. La sintaxis no puede ser más sencilla:

//Two way binding between neasted properties: Bind.TwoWay(()=> client.Area.Data.Name == this.AreaName); //On change action execute: Bind .OnChange(()=> client.Personal.Name) .Do(x => clientName = x);


No tengo conocimiento de ninguna biblioteca que haga esto, pero usted podría escribir su propia bastante fácilmente.

Aquí hay una base que descubrí en unos minutos que establece un enlace de datos bidireccional entre dos propiedades simples:

public static class Binder { public static void Bind( INotifyPropertyChanged source, string sourcePropertyName, INotifyPropertyChanged target, string targetPropertyName) { var sourceProperty = source.GetType().GetProperty(sourcePropertyName); var targetProperty = target.GetType().GetProperty(targetPropertyName); source.PropertyChanged += (s, a) => { var sourceValue = sourceProperty.GetValue(source, null); var targetValue = targetProperty.GetValue(target, null); if (!Object.Equals(sourceValue, targetValue)) { targetProperty.SetValue(target, sourceValue, null); } }; target.PropertyChanged += (s, a) => { var sourceValue = sourceProperty.GetValue(source, null); var targetValue = targetProperty.GetValue(target, null); if (!Object.Equals(sourceValue, targetValue)) { sourceProperty.SetValue(source, targetValue, null); } }; } }

Por supuesto, este código carece de algunas sutilezas. Las cosas para agregar incluyen

  • Comprobando que la source y el target están asignados
  • Comprobando que las propiedades identificadas por sourcePropertyName y targetPropertyName existen
  • Comprobando la compatibilidad de tipo entre las dos propiedades

Además, Reflection es relativamente lento (aunque es un punto de referencia antes de descartarlo, no es tan lento), por lo que es posible que desee utilizar expresiones compiladas en su lugar.

Por último, dado que la especificación de propiedades por cadena es propensa a errores, podría usar expresiones Linq y métodos de extensión. Entonces en lugar de escribir

Binder.Bind( source, "Name", target, "Name")

usted podría escribir

source.Bind( Name => target.Name);


Si definieras tus propiedades como DependencyProperty ''s, podrías hacerlo. Tanto WF como WPF tienen una implementación (el primer enlace es para WPF. Para WF es this ), por lo que debe decidir cuál usar, pero ambos deberían ser suficientes para sus necesidades.


Tal vez Bindable LINQ o Linq continuo pueden ayudar aquí. Si está intentando agregar propiedades de modelo que en realidad son "propiedades derivadas" de sus datos reales y actualizados, para facilitar el enlace de la interfaz de usuario, estos dos marcos deberían ayudar.


AutoMapper puede copiar valores entre dos instancias, pero debe escribir su propio código para que esto suceda automáticamente.