Я использую шаблон MVVM для создания приложения.В этом приложении у меня есть ComboBox, который связан с набором элементов и со свойством, содержащим выбранный элемент:
<ComboBox ItemsSource="{Binding Path=Persons, Mode=OneTime}"
SelectedValue="{Binding Path=SelectedPerson, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Коллекция с элементами для этого ComboBox инициализируется «текстом инструкции» какпервый элемент, а затем набор обычных элементов:
Persons.Add("Open Person...");
Persons.Add("Anders Andersson");
Persons.Add("Bengt Bengtsson");
Persons.Add("Carl Carlsson");
Persons.Add("Daniel Danielsson");
Я хотел бы иметь поведение для этого ComboBox, которое первоначально показывает текст инструкции (это, конечно, легко выполняется).Когда пользователь выбирает человека в ComboBox, приложение предпринимает какое-то действие (открывает выбранного человека), а затем сбрасывает текст инструкции.
На первый взгляд, это будет легко, если иметь это свойство для выбранного элемента.:
private string _selectedPerson = "Open Person...";
public string SelectedPerson
{
get
{
return _selectedPerson;
}
set
{
if (value != _selectedPerson)
{
OpenPerson(value);
OnPropertyChanged("SelectedPerson");
}
}
}
Моя идея заключалась в том, что когда пользователь выбирает что-либо, кроме текста инструкции в ComboBox, OpenPerson () будет вызываться с выбранным значением, но выбранное значение не будет сохранено в приватномполе (_selectedPerson).Затем я запускаю событие PropertyChanged, которое заставит ComboBox прочитать значение свойства SelectedPerson и обновить себя (SelectedValue).Поскольку поле _seletedPerson по-прежнему является текстом инструкции, ComboBox будет сбрасывать себя на это.
Это НЕ работает.
На самом деле все происходит так, как я ожидал.OpenPerson () вызывается с правильным параметром, а затем вызывается событие PropertyChanged.Однако действие GUI для изменения значения, показанного ComboBox, фактически выполняется ПОСЛЕ всего этого.Это означает, что независимо от того, какое значение я выбрал для SelectedPerson, ComboBox покажет элемент, который был выбран в графическом интерфейсе.
Есть ли элегантный способ обойти это?
На самом деле, яобошел это сам.Но он включал код в CodeBehind, два флага в ViewModel и некоторый неприятный код в свойстве SelectedPerson.Решение, ну, в общем, неудовлетворительно, если не сказать больше ...;) Итак, я надеялся, что кто-то умнее меня сможет найти лучшее решение! :)