Сбросить выбранный элемент combobox на наборе с помощью MVVM
Я использую ComboBox в моем приложении WPF и после MVVM. Существует список строк, которые я хочу показать в моем ComboBox.
XAML:
<ComboBox ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem}" />
Модель Вид:
public Collection<string> ItemsCollection; // Suppose this has 10 values.
private string _selectedItem;
public string SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
Trigger Notify of property changed.
}
}
Сейчас этот код работает абсолютно нормально. Я могу выбрать из вида, и я могу получить изменения в ViewModel, и если я изменю SelectedItem из моей ViewModel, я могу увидеть его в своем представлении.
Теперь вот чего я пытаюсь достичь. Когда я изменяю выбранный элемент из мое мнение мне нужно поставить галочку, что значение хорошо / плохо (или что-то еще) установить выбранный элемент, иначе не устанавливайте его. Поэтому моя модель представления меняется следующим образом.
public string SelectedItem
{
get { return _selectedItem; }
set
{
if (SomeCondition(value))
_selectedItem = value; // Update selected item.
else
_selectedItem = _selectedItem; // Do not update selected item.
Trigger Notify of property changed.
}
}
Теперь, когда я выполняю этот код и SomeCondition (value) возвращает false, SelectedItem возвращает старое строковое значение, но, на мой взгляд, выбранный элемент в ComboBox-это значение, которое я выбрал. Поэтому предположим, что у меня есть коллекция из 10 строк, отображаемых в моем ComboBox. Все значения хороши, кроме второго и четвертого элемента (SomeCondition возвращает false для 2-го и 4-го значения). Что я хочу, чтобы, если я выберу 2-й или 4-й элемент selectedItem, не изменялись. Но мой код делает это неправильно. Если я выбираю 2-й элемент, то view по-прежнему отображает 2-й элемент как выбранный. Я знаю, что в моем коде что-то не так. Но что это?
3 ответов
это очень интересный вопрос. Во-первых, я согласен с другими ребятами, что это не рекомендуется подход к обработке недопустимого выбора. Как предполагает @blindmeis,IDataErrorInfo
является одним из хороших способов его решения.
вернемся к самому вопросу. Решение, удовлетворяющее тому, что хочет @Faisal Hafeez:
public string SelectedItem
{
get { return _selectedItem; }
set
{
var oldItem=_selectedItem;
_selectedItem=value;
OnPropertyChanged("SelectedItem")
if (!SomeCondition(value)) //If does not satisfy condition, set item back to old item
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SelectedItem = oldItem),
DispatcherPriority.ApplicationIdle);
}
}
Dispatcher
- это элегантный способ обработки некоторой синхронизации пользовательского интерфейса во время другой синхронизации пользовательского интерфейса. Например, в этом случае необходимо сбросить выделение во время выделения обязательный.
вопрос в том, почему мы должны сначала обновить выбор. Это потому что SelectedItem
и SelectedValue
отдельно назначаются и какой дисплей на ComboBox
не зависит от SelectedItem
(может быть SelectedValue
, Я не уверен здесь). И еще один интересный момент-если SelectedValue изменения, SelectedItem
должно измениться, но SelectedItem
не обновляет SelectedValue
, когда она меняется. Таким образом, вы можете выбрать привязку к SelectedValue
так что вам не нужно назначать сначала.
попробуйте изменить XAML на this
<ComboBox ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox ItemsSource="{Binding ItemsCollection}" SelectedIndex="{Binding currSelection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
и в вашей VM
{
set{
currSelection = -1;
}
}