Domanda

Esistono framework di associazione dei dati (BCL o altro) che consentono l'associazione tra due proprietà CLR che implementano INotifyPropertyChanged e INotifyCollectionChanged ? Sembra che dovrebbe essere possibile fare qualcosa del genere:

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

Dove someSourceObject e someTargetObject sono solo POCO che implementano INotifyPropertyChanged . Tuttavia, non sono a conoscenza di alcun supporto BCL per questo, e non sono sicuro che ci siano framework esistenti che lo consentono.

AGGIORNAMENTO : dato che non esiste una biblioteca disponibile, ho deciso di scrivere la mia. È disponibile qui .

Grazie

È stato utile?

Soluzione

Ho scritto Truss per riempire il vuoto.

Altri suggerimenti

Non sono a conoscenza di alcuna libreria che fa questo, ma potresti scriverne una abbastanza facilmente.

Ecco una base che ho scoperto in pochi minuti che stabilisce un'associazione dati bidirezionale tra due proprietà semplici:

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);
                }
            };
    }
}

Naturalmente, questo codice manca di alcuni aspetti positivi. Le cose da aggiungere includono

  • Verifica che source e target siano assegnati
  • Verifica dell'esistenza delle proprietà identificate da sourcePropertyName e targetPropertyName
  • Verifica della compatibilità dei tipi tra le due proprietà

Inoltre, Reflection è relativamente lento (anche se confrontalo prima di scartarlo, non è così lento), quindi potresti voler usare espressioni compilate

Infine, dato che la specifica delle proprietà per stringa è soggetta a errori, è possibile utilizzare invece espressioni Linq e metodi di estensione. Quindi invece di scrivere

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

potresti scrivere

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

AutoMapper può copiare valori tra due istanze, ma devi scrivere il tuo codice per farlo accade automaticamente.

Forse LINQ associabile o linq continuo può aiutarti qui. Se stai provando ad aggiungere proprietà del modello che in realtà sono "proprietà derivate" dei tuoi dati effettivi e di aggiornamento, per semplificare il collegamento dell'interfaccia utente, questi due framework dovrebbero essere di aiuto.

Ho scritto un piccolo progetto Bind con pieno supporto per l'associazione tra azioni nidificate con azioni asincrone. La sintassi non può essere più semplice:

//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);

Se hai definito le tue proprietà come DependencyProperty potresti farlo. Sia WF che WPF ne hanno un'implementazione (il primo collegamento è per WPF. Per WF è questo ), quindi devi decidere quale utilizzare, ma entrambi dovrebbero essere sufficienti per le tue esigenze.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top