ItemsSource + Converter + Treeview не обновляется

Это довольно сложно, надеюсь, я смогу объяснить это достаточно ясно, чтобы кто-нибудь помог мне. У меня есть объект, назовем его менеджером, у менеджера есть набор людей, которыми он управляет, все люди реализуют 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));
}

Я как-то нарушаю привязку данных?

Что еще я могу проверить?

Конвертер просто просматривает каждый элемент в списке людей и выясняет, над какими проектами они работают, и добавляет имя проекта в выходной список.


person Kelly    schedule 01.04.2009    source источник


Ответы (1)


Преобразователь применяется к свойству, в котором хранится коллекция. Следовательно, он будет вызываться только в случае изменения самого экземпляра коллекции (но не в случае изменения элементов в коллекции). Один из способов обойти это — аннулировать коллекцию, когда вы хотите ее обновить.

Самый простой способ аннулировать свойство коллекции и снова запустить код преобразователя — это null удалить коллекцию и переназначить ее. Другой способ — получить BindingExpression ( через BindingOperations) и вызовите UpdateTarget. Наконец, вы можете привязаться к CollectionView (или его подкласс) и вызовите Refresh< /a> на нем.

И если вы действительно хотите решить проблему чисто, вы можете выполнить привязку к собственной реализации ICollectionView, который выполняет фильтрацию и вызывает события по мере необходимости.

person Kent Boogaart    schedule 01.04.2009
comment
Думаю, я понимаю, что вы говорите мне делать, но я не уверен, как это сделать с помощью hierarcicalDataTemplate. Если я правильно понимаю, я хочу обернуть свойство People в CollectionView и обновить CollectionView при изменении коллекции. Некоторый пример кода был бы большой помощью. - person Kelly; 01.04.2009
comment
Спасибо за помощь, я заработал, поместив свой список людей в ObservableCollection проектов, которые подписались на событие изменения коллекции людей и обновили себя. - person Kelly; 01.04.2009