web-dev-qa-db-fra.com

ComboBox SelectedItem vs SelectedValue

Le code suivant fonctionne comme prévu: MyProperty sur le modèle est mis à jour lorsque l'utilisateur sélectionne un nouvel élément dans la liste déroulante.

comboBox1.DataBindings.Add("SelectedValue", myModel, "MyProperty", true,
DataSourceUpdateMode.OnPropertyChanged);

Cependant, ce qui suit ne fonctionne pas de la même manière et la mise à jour du modèle n'est pas déclenchée tant que le focus d'entrée ne se déplace pas vers un autre contrôle du formulaire:

comboBox1.DataBindings.Add("SelectedItem", myModel, "MyProperty", true, 
DataSourceUpdateMode.OnPropertyChanged);

Quelqu'un sait-il pourquoi? Je ne sais même pas par où commencer pour enquêter sur la cause. Des indications dans la bonne direction pour commencer l'enquête ou une explication pure et simple seraient également appréciées.

À part: pour mes besoins, j'ai fini par lier à la fois SelectedItem et SelectedValue. De cette façon, j'obtiens des mises à jour instantanées de modèle basées sur des changements d'interface utilisateur (via la liaison SelectedValue), et des mises à jour d'interface utilisateur basées sur des modifications de modèle programmatique (via la liaison SelectedItem).

47
Adam Lear

Le contrôle ComboBox hérite du contrôle ListControl .

La propriété SelectedItem est un membre approprié du contrôle ComboBox. L'événement déclenché lors du changement est ComboBox.SelectionChangeCommitted

ComboBox.SelectionChangeCommitted

Se produit lorsque l'élément sélectionné a changé et que cette modification est affichée dans la zone de liste déroulante.

La propriété SelectedValue est héritée du contrôle ListControl. En tant que telle, cette propriété déclenchera le ListControl.SelectedValueChanged événement.

ListControl.SelectedValueChanged

Se produit lorsque la propriété SelectedValue change.

Cela dit, ils ne déclencheront pas l'événement INotifyPropertyChanged . PropertyChanged de la même façon, mais ils le feront quand même. La seule différence est dans l'événement de tir. SelectedValueChanged est déclenché dès qu'une nouvelle sélection est effectuée dans la partie liste du ComboBox, et SelectedItemChanged est déclenchée lorsque l'élément est affiché dans la partie TextBox du ComboBox.

En bref, ils représentent tous les deux quelque chose dans la partie liste du ComboBox. Ainsi, lors de la liaison d'une propriété, le résultat est le même, puisque l'événement PropertyChanged est déclenché dans les deux cas. Et comme ils représentent tous les deux un élément de la liste, ils sont probablement traités de la même manière.

Est-ce que cela aide?

EDIT # 1

En supposant que la partie liste du ComboBox représente une propriété (comme je ne peux pas le confirmer car je n'ai pas écrit le contrôle), la liaison de SelectedItem ou SelectedValue affecte la même collection à l'intérieur du contrôle. Ensuite, lorsque cette propriété est modifiée, la même chose se produit à la fin. Le INotifyPropertryPropertyChanged.PropertyChanged l'événement est déclenché sur la même propriété.

40
Will Marcouiller

Je soupçonne que la propriété SelectedItem du ComboBox ne change pas tant que le contrôle n'a pas été validé (ce qui se produit lorsque le contrôle perd le focus), tandis que la propriété SelectedValue change chaque fois que l'utilisateur sélectionne un élément.

Voici une référence aux événements de focus qui se produisent sur les contrôles:

http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.validated.aspx

6
George Howarth

Si vous voulez que Selected.Value soit travaillé, vous devez faire les choses suivantes:

1. Set DisplayMember
2. Set ValueMember
3. Set DataSource (not use Items.Add, Items.AddRange, DataBinding etc.)

Le point clé est Set DataSource!

2
isxaker

Il s'agit d'une "fonctionnalité" de longue date des contrôles de liste dans .NET dans mon expérience. Personnellement, je voudrais simplement me lier à la modification de la propriété SelectedValue et écrire le code supplémentaire nécessaire pour contourner cette "fonctionnalité" (comme avoir deux propriétés, se lier à une pour SelectedValue, puis, sur l'ensemble de cette propriété, mise à jour de la valeur de SelectedItem dans votre code personnalisé).

Quoi qu'il en soit, j'espère que cela aide = D

2

Si nous voulons nous lier à un dictionnaire, par exemple

  <ComboBox SelectedValue="{Binding Pathology, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                              ItemsSource="{x:Static RnxGlobal:CLocalizedEnums.PathologiesValues}" DisplayMemberPath="Value" SelectedValuePath="Key"
                              Margin="{StaticResource SmallMarginLeftBottom}"/>

alors SelectedItem ne fonctionnera pas alors que SelectedValue sera

1
Oyiwai