У меня есть ComboBox
, который привязан к свойству на моей модели ViewModel (от прослушивания на «VM».) Когда пользователь делает выбор на ComboBox
, он правильно обновляет свойство bound в моей виртуальной машине. В моем коде пользовательского интерфейса я подписался на событие PropertyChanged
на моей виртуальной машине.Как я могу правильно сбросить значение, связанное с ComboBox, из события PropertyChanged?
Как и должно быть, когда пользователь делает выбор в пределах ComboBox
, мое PropertyChanged
событие правильно выполняется в моем внутреннем коде интерфейса. Когда код пользовательского интерфейса улавливает изменение этого свойства, при определенных условиях выбора мне нужно остановить процесс и запросить у пользователя дополнительную информацию. Из пользовательского интерфейса я посылаю им диалог. Если они отменили диалог, я сброшу значение в виртуальной машине, которая связана с элементами управления ComboBox
SelectedValue
.
Это то, что я наблюдал. Когда операция отменяется пользователем, мое свойство VM устанавливается на новое значение. Однако, ComboBox
все еще показывает текстовое значение исходной записи, которая теперь изменилась. Как я могу заставить ComboBox
обновить себя из моего события PropertyChanged
? В этом случае я считаю, что это просто текстовая ошибка или числовое изменение индекса, которое ссылается на текстовые данные из связанной коллекции. Данные верны в VM, но значение отображения для ComboBox
неверно.
Пример
ComboBox Подробности
<ComboBox
ItemsSource="{Binding ListOfComboBoxDisplayObjects}"
SelectedValue="{Binding MySelectionIsAnEnumeration}"
DisplayMemberPath="Text"
SelectedValuePath="EnumerationValue"
Height="27" />
Извините за словесных свойств на VM, но это, чтобы объяснить, что происходит. Моя коллекция ListOfComboBoxDisplayObjects
представляет собой набор значений перечислителя, которые хранятся в пути в пределах SelectedValuePath
. Описательный текст для каждого значения вытягивается из ListOfComboBoxDisplayObjects
, который является специальным списком, строго созданным для пользовательского интерфейса. Это в основном связывает значение перечисления со значимым описанием.
ListOfComboBoxDisplayObjects Определение (внутри VM)
Edit # 1 - Добавлен это определение к моему примеру
private ObservableCollection<BindableEnumerationItem<Values>> _listOfComboBoxDisplayObjects;
public ObservableCollection<BindableEnumerationItem<Values>> ListOfComboBoxDisplayObjects
{
get { return _listOfComboBoxDisplayObjects; }
private set
{
if (value != _listOfComboBoxDisplayObjects)
{
_listOfComboBoxDisplayObjects= value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ListOfComboBoxDisplayObjects)));
}
}
}
MySelectionIsAnEnumeration Определение (Изнутри VM)
* Редактировать # 1: добавление этого определения кода.
private Values_mySelectionIsAnEnumeration ;
public Values MySelectionIsAnEnumeration
{
get { return _mySelectionIsAnEnumeration; }
set
{
//Double-checked this-- value is different on the second-call to change this value, once the UI cancels the operation.
if (value != _mySelectionIsAnEnumeration)
{
_mySelectionIsAnEnumeration= value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(MySelectionIsAnEnumeration)));
}
}
}
Соответствующие значения, связанные с ListOfComboBoxDisplayObjects
Эти значения генерируются в CTOR ВМ. Они фиксируются во всем приложении.
Пункт # 1
- Текст: "Это Foo"
- Ценность: Ценности.Foo
Item # 2:
- Текст: "Привет, я Bar."
- Значение: Values.Bar
Пункт # 3:
- Текст: ". Это Баз мне нужно задать вопрос, прежде чем я могу использовать"
- Значение: Values.Baz
PropertyChanged Event - Из интерфейса Back-End
private void VM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "MySelectionIsAnEnumeration":
if (VM.MySelectionIsAnEnumeration == Values.Baz)
{
//Prompt the user and get DialogResult.
bool answerGiven = AskAQuestionAndGetAResult();
if(!answerGiven)
VM.MySelectionIsAnEnumeration = Values.Foo;
}
break;
}
}
После выполнения приведенного выше кода, что я наблюдая, что значение VM.MySelectionIsAnEnumeration
действительно переходя к правильному значению Value.Foo
, когда пользователь отменяет операцию в пределах AskAQuestionAndGetAResult()
. Однако после того, как он закончил, ComboBox
все еще читает «Это Баз. Мне нужно задать вопрос, прежде чем я смогу использовать»., что, очевидно, является значением отображения, связанным с Value.Baz
.
Как обновить как базовое свойство VM, так и текст дисплея на CombobBox
, чтобы правильно отобразить значение, которое теперь хранится в VM.MySelectionIsAnEnumeration
?
Edit # 2
Ниже приведен код Efor мой BindableEnumerationItem
, что я использую в моих наблюдаемыми Коллекции для comboxes и списков. Это используется в моем приложении в более простых случаях и не вызвало никаких проблем. Обратите внимание, что это мой реальный, неизменный код. Я ничего не переименовал. Мои comboboxes могут связываться с каждым свойством Item
для типа безопасного свойства, а DisplayText
- текст дескриптора.
public class BindableEnumerationItem<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private T _item;
public BindableEnumerationItem(T item, string displayText)
{
_item = item;
_displayText = displayText;
}
private string _displayText;
public string DisplayText
{
get { return _displayText; }
set
{
if (value != _displayText)
{
_displayText = value;
PropertyChanged(this, new PropertyChangedEventArgs("DisplayText"));
}
}
}
public T Item
{
get { return _item; }
set
{
_item = value;
PropertyChanged(this, new PropertyChangedEventArgs("Item"));
}
}
}
Если представление не обновляет привязку, то где-то отсутствует уведомление или ошибка привязки. Можете ли вы показать «ListOfComboBoxDisplayObjects», его тип и «MySelectionIsAnEnumeration»? – Sinatr
@Sinatr, значения в 'ListOfComboBoxDisplayObjects' являются значениями, указанными в разделе ** Соответствующие значения, связанные с ListOfComboBoxDisplayObjects **. В этом случае тип перечислителя - «Значения». Это произвольные значения, которые я создал для упрощения примера. Что касается привязки, все операции привязки, как представляется, функционируют должным образом. Обычно, когда возникает проблема с привязкой, отладчик выводит проблему в окно вывода Debug. В этом случае я не вижу сообщений или ошибок после повторного назначения. – RLH
Чтобы быть ясным, привязка корректно работает и была дважды проверена, когда пользователи выбирают 'Foo' или' Bar'. Даже «Баз» работает правильно, когда пользователь отвечает на запросы. Однако, когда операция отменена, элемент пользовательского интерфейса внутри ComboBox не обновляет текст, но я уверен, что базовое значение в моей виртуальной машине является правильным. – RLH