У меня горе с ComboBox, не отражающим изменения в свойствах коллекции, к которой привязан его ItemsSource.
Существует дерево, состоящее из видимой коллекции категорий объектов категории, содержащих объекты настройки. Некоторые настройки определяют имена презентаций для домена значений, разрешенных для других настроек. Они распределены по нескольким категориям, но небольшая магия с LINQ создает ObservableCollection, в которой ChannelCategory предоставляет свойства ChannelNumber и ChannelTitle.
ChannelCategory.ChannelTitle — это StringSetting, ChannelNumber — это int, неизменяемое значение идентификатора, для которого ChannelTitle предоставляет отображаемую строку. Опуская обильные, но не относящиеся к делу другие узлы, мы имеем следующее:
Channels
ChannelCategory
ChannelNumber = 1
ChannelTitle = "caption for channel one"
ChannelCategory
ChannelNumber = 2
ChannelTitle = "caption for channel two"
ChannelCategory
ChannelNumber = 3
ChannelTitle = "caption for channel three"
...
Эта коллекция каналов подготавливается и предоставляется свойством класса, созданного и добавленного в словарь ресурсов окна в XAML (доступный как StaticResource). Такое расположение позволяет мне декларативно привязать поле со списком к каналам.
<ComboBox VerticalAlignment="Center" Grid.Column="2"
ItemsSource="{Binding Source={StaticResource cats}, Path=Channels}"
DisplayMemberPath="ChannelTitle.Editor"
SelectedValuePath="ChannelNumber"
SelectedValue="{Binding Editor}"
/>
Все это работает, но изменения значения ChannelTitle в другом месте не отражаются в значениях, отображаемых в списке со списком.
Различные приемы отладки с точками останова и событием DropDownOpened позволили мне убедиться, что обновления имеются в коллекции, на которую ссылается ItemsSource.
И, наконец, мы доходим до тайны. Почему поле со списком не обнаруживает изменения в элементах коллекции? Сама коллекция является ObservableCollection, поэтому она должна уведомлять об изменениях свойств.
Все элементы коллекции — это ChannelCategory, который является DependencyObject, а ChannelCategory.ChannelTitle — это DependencyProperty.
Я думаю, проблема в том, что я не добавляю и не удаляю элементы из коллекции, так что коллекция состоит из тех же элементов и, следовательно, не изменилась.
Может ли кто-нибудь предложить стратегию внесения изменений в ChannelTitle, чтобы коллекция каналов уведомляла об изменениях, чтобы поле со списком обновлялось?
Предложение Рэйчел закончилось так, как показано ниже. В контексте моего приложения было значительно больше сложности, потому что каждая ChannelCategory владеет набором объектов настроек, поэтому изменяющееся значение является свойством объекта в наборе, который является свойством объекта в наборе, к которому привязан ItemsSource. . Но суть предложения Рейчел просто нуждалась в применении на двух уровнях.
public class ObservableChannelCollection : ObservableCollection<ChannelCategory>
{
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
foreach (ChannelCategory channel in e.NewItems)
channel.PropertyChanged += channel_PropertyChanged;
if (e.OldItems != null)
foreach (ChannelCategory channel in e.OldItems)
channel.PropertyChanged -= channel_PropertyChanged;
base.OnCollectionChanged(e);
}
void channel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e);
}
}