ItemsSource + Converter + Treeview не обновляется
-
22-08-2019 - |
Вопрос
Это довольно сложно, надеюсь, я смогу объяснить это достаточно ясно, чтобы кто-нибудь мог мне помочь.У меня есть объект, назовем его Менеджером, у Менеджера есть набор людей, которыми он управляет, все люди реализуют IPerson, но разные типы людей имеют разные свойства.Я хочу отобразить этого менеджера в дереве, а под узлом менеджера я хочу показать все проекты, которыми он управляет, которые можно определить по людям, которыми он управляет.
Итак, мы планируем использовать конвертер для преобразования человека в список проектов.Вот XAML:
<HierarchicalDataTemplate DataType="{x:Type ui:Manager}">
<TextBlock Text="{Binding Path=Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate.ItemsSource>
<Binding Path="People">
<Binding.Converter>
<configUtil:ProjectListConverter/>
</Binding.Converter>
</Binding>
</HierarchicalDataTemplate.ItemsSource>
</HierarchicalDataTemplate>
Мой класс Person реализует INotifyPropertyChanged, а список, содержащий людей, реализует INotifyCollectionChanged. Этот код отлично работает, когда я устанавливаю ItemsSource в виде дерева, менеджеры отображаются со своим списком проектов.
Однако когда я добавляю нового человека в список людей, TreeView не обновляется.Во время отладки я вижу, что CollectionChanged срабатывает с действием «Добавить» и добавленным элементом.Кроме того, событие CollectionChanged не является нулевым, поэтому я знаю, что пользовательский интерфейс наблюдает за ним.Но конвертер не выполняется при добавлении элемента.
вот метод Add для списка, содержащего объекты IPerson:
public void Add(T item)
{
list.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
Я как-то нарушаю привязку данных?
Что еще я могу проверить?
Конвертер просто просматривает каждый элемент в списке «Люди», определяет, над какими проектами они работают, и добавляет название проекта в выходной список.
Решение
Конвертер применяется к свойству, в котором хранится коллекция.Следовательно, он будет вызываться только в том случае, если изменится сам экземпляр коллекции (а не если изменяются элементы в коллекции).Одним из способов решения этой проблемы было бы сделать коллекцию недействительной, когда вы хотите ее обновить.
Самый простой способ сделать свойство коллекции недействительным и снова запустить код преобразователя — это null
извлеките коллекцию и переназначьте ее.Другой способ — получить BindingExpression
(с помощью BindingOperations
) и позвоните UpdateTarget
.Наконец, вместо этого вы можете привязаться к CollectionView
(или его подкласс) и вызовите Refresh
в теме.
И если вы Действительно хотите решить проблему чисто, вы можете привязать свою собственную реализацию ICollectionView
который выполняет фильтрацию и генерирует события по мере необходимости.