2010-11-11 37 views
2

J'ai cette situation où j'ai plusieurs commandes liées les unes aux autres. J'utilise la liaison bidirectionnelle pour la Current/SelectedValue des contrôles, de sorte que lorsqu'un utilisateur change la valeur, la modification est reflétée dans la propriété de mon viewmodel. La chose est, après la liaison déclenche la modification au setter de la propriété modifiée, j'ai besoin de changer les autres contrôles, basé sur le premier, mettre à jour l'interface utilisateur, puis envoyer un seul événement avec les nouvelles valeurs de toutes les propriétés affectées. Je pensais faire quelque chose dans les lignes de ce (genre de quelque chose de similaire à IEditableObject):Augmente l'événement seulement après que les propriétés dépendantes aient changé la valeur

public string PropA 
{ 
    get{(...)} 
    set 
    { 
     BeginEdit("PropA"); 
     PropA = value; 
     PropB = SomeValueDependentOnA; 
     PropC = SomeValueDependentOnA; 
     OnPropertyChanged("PropA"); 
     EndEdit("PropA");    //this is propA so send the event   
} 

public string PropB 
{ 
    get{(...)} 
    set 
    { 
     BeginEdit("PropB"); 
     PropB = value; 
     PropA = SomeValueDependentOnB; 
     PropC = SomeValueDependentOnB; 
     OnPropertyChanged("PropB"); 
     EndEdit("PropB");   
} 

(...) 

begin/méthodes de EndEdit ne feraient pas grand chose, juste vérifier si l'hélice qui a commencé l'opération est le même que appelle l'endedit, donc plus loin serait ignoré. Le EndEdit nous assurerons que seulement dans le setter de PropA pouvons nous être certains que toutes les propriétés ont changé et nous pouvons envoyer l'événement, sorte de transaction.

Bien que je pense que cela fonctionne, je pense que c'est un peu trop à faire sur le setter et le début/endedit semble trop pour cette chose simple.

Peut-être que l'utilisation de la liaison bidirectionnelle n'est pas la meilleure option pour ce cas et je devrais faire les mises à jour des méthodes dans le code derrière au lieu des setters de la propriété.

Avez-vous des suggestions sur la façon de procéder autrement?

Répondre

0

La méthode standard que je l'ai vu de le faire est la suivante:

set 
{ 
    if (PropA != value) 
    { 
     PropA = value; 
     OnPropertyChanged("PropA"); 
    } 
} 

De cette façon, vous déclenchez seulement frapper les changements lorsque les changements de valeur, et les appels suivants (déclenchés par des valeurs dépendantes) ne déclenchera pas d'autres changements .

+0

Mais comment puis-je mettre à jour les autres propriétés? – Jay

+0

Vous pouvez mettre à jour les autres directement dans le 'if' ou dans le gestionnaire PropertyChanged. –

+0

Je pensais à la mise à jour dans le gestionnaire PropertyChanged, mais le problème est qu'il va rebondir entre les setters de propriétés et l'événement d'opération final sera renvoyé plusieurs fois (c'est ce que j'essaie d'éviter). – Jay

1

IMHO approche la plus «casher» ici est d'utiliser DependecyProperties ayant le code de conflit à l'intérieur de leurs gestionnaires de coercition, comme le font les composants de l'interface utilisateur.

Une autre méthode consiste à appliquer une logique sur les champs VM, et non sur les propriétés, puis à déclencher UpdateTarget() pour les liaisons.

+0

Je vais essayer avec DependencyProperties. Je n'ai pas bien compris l'autre façon dont vous parlez, pourriez-vous être un peu plus clair (j'ai eu la partie de la partie UpdateTarget mais comment/où j'appliquerais la logique aux champs?). La deuxième suggestion, je devrais configurer les liaisons en utilisant le mode explicite, non? – Jay