Question

Existe-t-il des infrastructures de liaison de données (BCL ou autre) autorisant la liaison entre deux propriétés CLR qui implémentent INotifyPropertyChanged et INotifyCollectionChanged ? Il semble qu'il devrait être possible de faire quelque chose comme ceci:

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

someSourceObject et someTargetObject ne sont que des objets POCO qui implémentent INotifyPropertyChanged . Cependant, je ne suis au courant d'aucun soutien de la BCL à cet égard et je ne sais pas s'il existe des cadres existants qui le permettent.

MISE À JOUR : étant donné qu’il n’existe aucune bibliothèque disponible, j’ai décidé de rédiger la mienne. Il est disponible ici .

Merci

Était-ce utile?

La solution

J'ai écrit Traversez pour combler le vide.

Autres conseils

Je ne suis au courant d'aucune bibliothèque qui le fasse - mais vous pouvez écrire assez facilement.

Voici une base que j'ai créée en quelques minutes pour établir une liaison de données bidirectionnelle entre deux propriétés 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);
                }
            };
    }
}

Bien sûr, ce code manque de quelques subtilités. Les choses à ajouter incluent

  • Vérification de l'attribution de source et de cible
  • Vérification de l'existence des propriétés identifiées par sourcePropertyName et targetPropertyName
  • Vérification de la compatibilité des types entre les deux propriétés

De plus, Reflection est relativement lente (bien que vous la testiez avant de la supprimer, ce n'est pas celle ), vous pouvez donc utiliser des expressions compilées.

Enfin, étant donné que spécifier des propriétés par chaîne est sujet à des erreurs, vous pouvez utiliser des expressions et des méthodes d'extension Linq. Puis au lieu d'écrire

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

vous pourriez écrire

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

AutoMapper peut copier des valeurs entre deux instances, mais vous devez écrire votre propre code pour le faire. se produire automatiquement.

Peut-être Bindable LINQ ou linq continu peut aider ici. Si vous essayez d'ajouter des propriétés de modèle qui sont en réalité des "propriétés dérivées". de vos données actuelles de mise à jour, pour faciliter la liaison de votre interface utilisateur, ces deux cadres devraient vous aider.

J'ai écrit un petit projet Bind avec une prise en charge complète de la liaison entre les actions de liaison asynchrone des propriétés non alignées. Le sintaxe ne peut pas être plus simple:

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

Si vous avez défini vos propriétés comme DependencyProperty Vous pouvez le faire. WF et WPF ont tous deux une implémentation (le premier lien concerne WPF. Pour WF, il s'agit de this ), vous devez donc choisir lequel utiliser - mais les deux devraient suffire à vos besoins.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top