2011-05-10 3 views
2

J'ai un comportement étrange quand j'associe et combobox à mon viewmodel. Le comportement est le suivant, quand je change la valeur choisie du combo je fais une validation de la nouvelle valeur et si cette nouvelle valeur est invalide je garde l'ancienne valeur et rejette la nouvelle, de cette façon je n'élève pas le Inotifypropertychanged, mais le getter de la propriété associée à la combobox est appel quand même, cela récupère l'ancienne valeur que je veux montrer, mais à la place la combobox montre la nouvelle valeur, même si la valeur sélectionnée du combo est la valeur ancienne et correcte, J'ai vérifié en mode débogage. Je ne sais pas comment je peux résoudre cela parce que je n'ai jamais vu ce genre de comportement, toutes les suggestions seraient très appréciées.WPF ComboBox MVVM comportement étrange

C'est le code du XAML

<ComboBox Height="23" Name="cbxStatus" HorizontalAlignment="Left" 
      ItemsSource="{Binding Path=Status, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
      SelectedItem="{Binding Path=SelectedStatus, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
      DisplayMemberPath="Value" Width="130" VerticalAlignment="Center" 
      IsEnabled="{Binding Path=StatusEnable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

c'est le code viewmodel, la propriété

public Config SelectedStatus 
{ 
    get 
    { 
     if (ApplicationAction == ApplicationAction.Add) 
     { 
      base.Object.State = configManager.BudgetInitStatus(); 
      StatusEnable = false; 
     } 
     else 
     { 
      StatusEnable = true; 
     } 
     return base.Object.State; 
    } 
    set 
    { 
     if (base.Service.CanChangeBudgetStatus(base.Object, value)) 
     { 
      base.Object.State = value; 
      base.Object.IsDirty = true; 
     } 
     RaiseOnPropertyChanged("SelectedStatus"); 
     RaiseOnPropertyChanged("AssociateOrderButtonVisibility"); 
    } 
} 

Merci pour l'aide

Répondre

2

Configuration de votre liaison aux

IsAsync=True 

fonctionnera.

+0

Salut merci à la fois pour les réponses, j'ai essayé les deux possibilités et aussi combiné les deux mais dans mon cas c'était celui qui a fonctionné, bien que je pense que les deux sont un peu hacky, je ne comprends pas pourquoi celui-ci fonctionne, J'ai lu dans msdn que c'est juste pour obtenir une propriété plus tard dans le processus de liaison, pour ainsi dire. Je pense que combobox devrait être "intelligent" assez pour voir que quand la propriété selecteditem est "notifiée" est devrait montrer cette valeur et non celle précédemment choisie ...mais c'est mon opinion. Merci encore une fois pour l'aide –

0

Lorsque l'utilisateur modifie la valeur dans la liste déroulante , il est changé dans la combobox, quel que soit votre viewmodel.

Si vous modifiez cette valeur et ne déclenchez pas de notification de modification de propriété, votre viewmodel et votre vue ne seront plus synchronisés.

En résumé, lorsque vous rejetez la valeur sélectionnée, vous avez toujours besoin de la notification de modification de propriété.

+1

Même avec une notification de modification (dont il dispose), WPF ignore la modification car elle attend une notification de modification à ce moment précis. Ce à quoi il ne s'attend pas, c'est que la valeur soit autre chose que ce qu'elle fournit à l'auteur de la propriété. –

+0

Oui, monsieur. – Jay

4

Comme indiqué dans mon commentaire à Jay, le problème ici est que WPF définit la valeur et n'écoute pas votre notification de changement (après tout, c'est attendu). Ce que vous devez faire est d'élever la notification de changement de propriété en dehors du contexte du message courant. Vous pouvez le faire en utilisant le répartiteur, par exemple:

set 
{ 
    if (!valid) 
    { 
     // value is unchanged 
     Dispatcher.BeginInvoke(delegate { this.OnPropertyChanged(...) }); 
     return; 
    } 

    // value is changed here 
} 

Cela permettra d'assurer les données actuelles un message de liaison est exécuté, un message séparé indique WPF que, « en fait, la valeur que vous venez de donner à mon setter est pas plus la valeur actuelle ". Vous pouvez également utiliser SynchronizationContext si vous préférez. De toute façon, j'avoue que c'est un peu hacky. Malheureusement, je ne connais pas de moyen de contourner cela. Le fait est que WPF suppose que la valeur qu'il transmet à votre setter est la valeur effective de la propriété. Aucune quantité de notifications de modification de propriété dans le contexte de l'opération de liaison ne le convaincra autrement.

+0

+1 de moi. Je m'en souviendrai certainement. – Willem

+0

Kent, que diriez-vous sont les inconvénients potentiels d'utiliser 'Async = True' pour accomplir cela? – Jay