J'utilise le modèle MVVM pour créer une application. Dans cette application, j'ai un ComboBox qui est lié à un colletion d'articles et à une propriété contenant l'élément sélectionné:WPF: Réinitialisation d'une zone de liste déroulante après modification
<ComboBox ItemsSource="{Binding Path=Persons, Mode=OneTime}"
SelectedValue="{Binding Path=SelectedPerson, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
La collection avec les éléments de cette zone de liste déroulante est initialisé avec un « texte d'instruction » comme le premier élément, puis un tas d'objets ordinaires:
Persons.Add("Open Person...");
Persons.Add("Anders Andersson");
Persons.Add("Bengt Bengtsson");
Persons.Add("Carl Carlsson");
Persons.Add("Daniel Danielsson");
le comportement que je voudrais avoir pour cette ComboBox est qu'il montre d'abord le texte d'instructions (ce qui est bien sûr facile à réaliser). Lorsque l'utilisateur sélectionne une personne dans la zone de liste déroulante, l'application effectue une action (ouvre la personne sélectionnée) et la réinitialise ensuite au texte d'instruction.
Comme d'abord pensé que ce serait facile en ayant cette propriété pour l'élément sélectionné:
private string _selectedPerson = "Open Person...";
public string SelectedPerson
{
get
{
return _selectedPerson;
}
set
{
if (value != _selectedPerson)
{
OpenPerson(value);
OnPropertyChanged("SelectedPerson");
}
}
}
Mon idée était que lorsque l'utilisateur sélectionne autre chose que le texte d'instructions dans la zone de liste déroulante, OpenPerson() sera appelé avec la valeur sélectionnée, mais la valeur sélectionnée ne sera pas stockée dans le champ privé (_selectedPerson). Ensuite, je déclenche l'événement PropertyChanged qui fera lire la valeur ComboBox de la propriété SelectedPerson et se mettre à jour (SelectedValue). Parce que le champ _seletedPerson est toujours le texte d'instruction, le ComboBox se réinitialisera à cela.
Cela ne fonctionne PAS.
En fait, tout semble se passer comme prévu. OpenPerson() est appelé avec le bon paramètre, puis l'événement PropertyChanged est déclenché. Cependant, l'action de l'interface graphique pour changer la valeur affichée par la ComboBox est effectivement effectuée après tout cela. Cela signifie que, quelle que soit la valeur de SelectedPerson, le composant ComboBox affiche l'élément sélectionné dans l'interface graphique.
Existe-t-il un moyen élégant de contourner ce problème?
En fait, je me suis débrouillé tout seul. Mais cela impliquait du code dans CodeBehind, deux drapeaux dans le ViewModel et du code méchant dans la propriété SelectedPerson. La solution n'est pas satisfaisante pour le moins ...;) Donc, j'espérais que quelqu'un de plus intelligent que moi pourrait trouver une meilleure solution! :)
Bien sûr! L'utilisation d'un gestionnaire SelectionChanged est la solution la plus simple. Je pensais tellement à la façon de faire cela dans le ViewModel que je n'ai jamais pensé à ça. Bien sûr, je préférerais que ma solution ci-dessus fonctionne, donc je n'aurais pas besoin de code dans mon code, mais évidemment ce n'est pas le cas. Merci Ingó! :) – haagel