57 votes

ComboBox SelectedItem vs SelectedValue

Le code suivant fonctionne comme on peut s'y attendre - 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);

La méthode suivante, cependant, 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 curseur de l'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 en rechercher la cause. Des indications dans la bonne direction pour commencer l'enquête ou une explication franche seraient également appréciées.

Aside pour mes besoins, j'ai fini par me lier aux deux SelectedItem y SelectedValue . De cette façon, j'obtiens des mises à jour instantanées du modèle en fonction des modifications de l'interface utilisateur (par l'intermédiaire de la fonction SelectedValue et les mises à jour de l'interface utilisateur basées sur les modifications du modèle programmatique (par le biais de l'application SelectedItem de liaison).

49voto

Will Marcouiller Points 11649

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

El SelectedItem est un membre propre de la propriété ComboBox contrôle. L'événement qui est déclenché lors d'un changement est ComboBox.SelectionChangeCommitted

ComboBox.SelectionChangeCommitted

Se produit lorsque l'élément sélectionné a changé et que ce changement est affiché dans la ComboBox.

El SelectedValue est hérité de la propriété ListControl contrôle. En tant que telle, cette propriété déclenchera le ListControl.SelectedValueChanged événement.

ListControl.SelectedValueChanged

Se produit lorsque la propriété SelectedValue est modifiée.

Cela dit, ils ne vont pas virer le INotifyPropertyChanged . PropertyChanged l'événement est le même, mais ils le feront quand même. La seule différence réside dans l'événement de mise à feu. SelectedValueChanged est déclenché dès qu'une nouvelle sélection est effectuée dans la partie liste de la ComboBox, et SelectedItemChanged est déclenché lorsque l'élément est affiché dans la partie TextBox de la ComboBox.

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

Cela vous aide-t-il ?

EDIT #1

En supposant que la partie liste de la ComboBox représente une propriété (ce que je ne peux pas confirmer puisque je n'ai pas écrit le contrôle), la liaison de l'un ou l'autre des éléments suivants SelectedItem o 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 site INotifyPropertryPropertyChanged.PropertyChanged est déclenché sur la même propriété.

0 votes

Ordre des événements lorsque tous sont abonnés : 1 SelectionChangeCommitted, 2 SelectedValueChanged, 3 SelectedIndexChanged

0 votes

J'ai trouvé ceci sur MSDN : L'événement SelectionChangeCommitted est levé uniquement lorsque l'utilisateur modifie la sélection de la ComboBox, et vous pouvez créer un gestionnaire pour cet événement afin de fournir une gestion spéciale pour la ComboBox lorsque l'utilisateur modifie l'élément sélectionné dans la liste. Toutefois, en fonction de la configuration de la boîte combinée et de la façon dont l'utilisateur modifie l'élément sélectionné, l'événement SelectionChangeCommitted peut ne pas être déclenché. Vous pouvez également gérer l'événement SelectedIndexChanged, mais notez que cet événement se produit, que l'indice soit modifié par le programme ou par l'utilisateur.

7voto

George Howarth Points 1364

Je soupçonne que la propriété SelectedItem de la 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), alors 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 mise au point qui se produisent sur les contrôles :

http://msdn.microsoft.com/en-us/library/system.Windows.forms.control.validated.aspx

0 votes

Une meilleure réponse que la mienne. Il est également important de souligner que vous ne pourrez pas utiliser SelectedItem lorsqu'il est lié à SelectedValue, car il ne sera pas encore mis à jour. Si je me souviens bien, vous devez utiliser la récupération de la collection Items du contrôle de liste par SelectedIndex.

2voto

D'après mon expérience, il s'agit d'une "caractéristique" de longue date des contrôles de liste dans .NET. Personnellement, je me contenterais de me lier à la modification de la propriété SelectedValue et d'écrire le code supplémentaire nécessaire pour contourner cette "fonctionnalité" (par exemple, en ayant deux propriétés, en se liant à l'une d'entre elles pour SelectedValue, puis, lors de la définition de cette propriété, en mettant à jour la valeur de SelectedItem dans votre code personnalisé).

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

1 votes

J'ai fini par mettre en place deux liaisons - une à SelectedValue et une à SelectedItem - et je n'ai pas eu besoin de code personnalisé au-delà :)

2voto

Mikhail Points 1033

Si vous voulez que Selected.Value fonctionne 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 !

0 votes

Le mien fonctionne avec SelectedValue en ne fixant que DataSource et DisplayMember, mais pas ValueMember. J'ai été surpris.

0voto

Oyiwai Points 326

Si nous voulons nous lier à un dictionnaire ie

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

SelectedItem ne fonctionnera pas alors que SelectedValue le fera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X