У меня есть объект 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 отключен! Я понятия не имею, как это произошло, но мне очень приятно, что я, наконец, дошел до сути проблемы.