2010-01-13 13 views
5

J'ai un contrôle avec un ComboBox:Modification de la valeur d'un DependencyProperty à l'intérieur du PropertyChangedCallback pour cette DependencyProperty

<ComboBox x:Name="TraceComboBox" 
      ItemsSource="{Binding SingleChannelList}" 
      SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, 
         AncestorType={x:Type cc:LogicTriggerSimpleLevelControl}}, 
         Path=SelectedTrace, Mode=TwoWay}"> 

Voici le PropertyChangedCallback pour la propriété SelectedTrace dans le OuterControl contenant le ComboBox:

private static void OnSelectedTraceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    OuterControl oc = d as OuterControl ; 
    oc.UpdateSelectedTrace(); 
} 

private void UpdateSelectedTrace() 
{ 
    ViewModelType vm = DataContext as ViewModelType; 
    if (vm != null) 
    { 
     if (vm.SingleChannelList != null) 
     { 
      SelectedTrace = vm.SingleChannelList[0]; 
     } 
    } 
} 

Par ma logique, ce qui suit devrait se produire:

Je selec t le 3ème objet dans ComboBox (SingleChannelList[2]) et le gestionnaire de changement se produit. Il passe ensuite dans la routine UpdateSelectedTrace(). À ce stade, la valeur de SelectedTrace est bien sûr SingleChannelList[2]. Maintenant, la routine UpdateSelectedTrace() définit de force la propriété SelectedTrace sur le 1er objet de la liste (SingleChannelList[0]), ce qui déclenche un autre gestionnaire de changement imbriqué dans le premier. "SelectedTrace" est maintenant égal à SingleChannelList [0], et donc le ComboBox devrait également montrer SingleChannelList [0] comme sa sélection.

Tout cela se passe quand je suis avec le débogueur jusqu'à ce que le éhonté dernière phrase, qui joue plutôt comme ceci:

SelectedTrace est maintenant égal à SingleChannelList[0], mais les ComboBox affiche SingleChannelList[2] comme élément sélectionné. J'ai essayé UpdatingTarget sur le BindingExpression et encore, la propriété SelectedTrace détient la valeur SingleChannelList[0] tandis que le ComboBox continue à afficher SingleChannelList[2]. Ces fixations sont sécurisées et testées et ont toujours fonctionné jusqu'à ce que j'essaye de le faire. Quelqu'un peut-il me dire pourquoi cela ne fonctionne pas correctement?

Merci

Répondre

2

Cela ressemble à un scénario de propriété de dépendance « de la contrainte de valeur ». La contrainte de valeur «pousse» la valeur de la propriété à une valeur valide basée sur une valeur souhaitée. En savoir plus ici:

Dependency Property Callbacks and Validation

+1

J'ai trouvé que, étant donné que la modification d'origine provient de la boîte qui change, cela ne fonctionne toujours pas. Au lieu de cela, j'ai juste mis la boîte après que tout est fait et ça fonctionne bien. Hacky mais fonctionne. La vraie question est POURQUOI mon scénario original ne fonctionne-t-il pas? – Kamiikoneko

0

Je crois que c'est une optimisation des performances par le cadre WPF. L'origine de la mise à jour de la propriété n'obtient pas un événement propertychanged (bien, l'équivalent de la liaison) pour se re-mettre à jour, puisque c'est l'origine de la modification. Vous pouvez forcer une mise à jour à l'aide d'un IdentityConverter (ValueConverter qui renvoie uniquement la valeur transmise) dans la liaison.