У меня есть объект Activity со многими свойствами. Один из них выглядит следующим образом:
public ActivityStatus Status
{
get { return status; }
set { status = value; NotifyPropertyChanged("Status"); }
}
Класс ActivityStatus имеет только два свойства:
public Guid Guid
{
get { return guid; }
set { guid = value; NotifyPropertyChanged("Guid"); }
}
public string Name
{
get { return name; }
set { name = value; NotifyPropertyChanged("Name"); }
}
и Equals:
public override bool Equals(object otherObject)
{
if (!(otherObject is ActivityStatus)) return false;
return Equals(otherObject as ActivityStatus);
}
public bool Equals(ActivityStatus otherStatus)
{
if (!(otherStatus is ActivityStatus) || otherStatus == null) return false;
return Guid == otherStatus.Guid && Name == otherStatus.Name;
}
У меня есть класс ActivityViewModel как DataContext класса ActivityView. ActivityViewModel имеет свойство Activity типа Activity и, среди прочих, свойство ActivityStatuses типа ObservableCollection<ActivityStatus>. В ActivityView у меня есть ComboBox, объявленный следующим образом:
<ComboBox ItemsSource="{Binding ActivityStatuses}"
SelectedItem="{Binding Activity.Status, Mode=TwoWay}"
DisplayMemberPath="Name" />
Это позволяет мне выбрать ActivityStatus из ComboBox, и это правильно обновляет свойство Status объекта Activity в свойстве Activity модели viewmodel. Проблема заключается в двусторонней привязке... при загрузке нового Activity, ComboBox.SelectedItem не обновляется, чтобы показать значение свойства Activity.Status.
Используя это объявление ComboBox, SelectedItem привязано к объекту ActivityStatus в Activity, и это другой объект для объекта с теми же значениями в свойстве viewmodel ActivityStatuses. Поэтому WPF Framework не считает, что элементы одинаковы и не выбирает элемент в ComboBox.
Если я назначу элемент из коллекции с теми же значениями в свойство Activity.Status после загрузки каждого Activity, то ComboBox найдет совпадение в своей коллекции ItemsSource и правильно установит свойство SelectedItem отображая значение. Я действительно не хочу этого делать, хотя, поскольку у меня есть много других подобных свойств в классе Activity, и мне придется повторять этот код в любом месте, где бы я ни хотел, привязаны к ComboBox es.
Итак, я также попробовал привязку к свойству ActivityStatus.Guid следующим образом:
<ComboBox ItemsSource="{Binding ActivityStatuses}"
SelectedValue="{Binding Activity.Status.Guid, Mode=TwoWay}"
SelectedValuePath="Guid"
DisplayMemberPath="Name" />
Это правильно выбрало объект с тем же Guid, что и в свойстве Activity.Status из коллекции ComboBox.ItemsSource при загрузке различных объектов Activity. Проблема с этим методом заключается в том, что SelectedValue привязан к свойству ActivityStatus.Guid в объекте ActivityStatus, и поэтому при изменении значений в пользовательском интерфейсе обновляется только свойство "Guid" объекта ActivityStatus оставив имя без изменений. Объект в свойстве Activity.Status не изменяется, кроме значения его свойства Guid.
Как вы можете видеть, я также попытался реализовать метод Equals, поскольку я предположил, что ComboBox будет использовать это для сравнения объектов, но это не имеет никакого значения. Итак, наконец, я в недоумении и очень хочу найти простой способ решить эту проблему... надеюсь, есть простое свойство, которое я пропустил на ComboBox.
Я просто хочу иметь возможность выбрать элемент в ComboBox и соответствующим образом изменить объект Activity.Status и изменить значение свойства Activity.Status из кода и соответствующим образом обновить ComboBox.SelectedItem. Я был бы признателен за любые советы.
ОБНОВЛЕНИЕ → >
Прочитав ответ "Ответ", я попробовал его образец кода в новом решении и увидел, что он работает так, как ожидалось. Затем я внимательно просмотрел его код и увидел, что он такой же, как у меня, поэтому снова запустил мое собственное решение (впервые с этого поста). К моему большому удивлению, он работал так, как я ожидал, без меня меняя код!
Это сильно меня озадачило, и я потратил некоторое время, чтобы узнать, что произошло. Оказывается, проблема была в Visual Studio 2010! Я добавил методы Equals к моим типам данных в качестве последнего этапа. По какой-то причине Visual Studio не создала проект типа данных при запуске приложения.
Таким образом, приложение должно было использовать старый DLL файл, и мои изменения не использовались... Я действительно задавался вопросом, почему мои точки разрыва в методах Equals никогда не попадали. Это привело к моему предположению, что внедрение методов Equals не помогло. Сегодня Visual Studio имеет такое же поведение и что я узнал, что произошло.
Я проверил порядок сборки проекта в своем решении, но он перечисляет проект типа данных в правильном месте в порядке. Однако при запуске приложения окно вывода в Visual Studio показывает, что DLL проекта загружается в другом порядке. Я не уверен, почему запуск приложения больше не выполняет полную сборку, но, по крайней мере, я знаю, что мне нужно создать этот проект после внесения изменений в него перед запуском приложения.
ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ → >
Я только выяснил, почему мой проект типа данных не строился... Я посмотрел в окне Configuration Manager и увидел, что платформа некорректна для этого проекта, а флажок Build отключен! Я понятия не имею, как это произошло, но мне очень приятно, что я, наконец, дошел до сути проблемы.