Question

This one is fairly complex, hopefully I can make this clear enough for somebody to help me out. I have an object lets call it a Manager, the Manager has a collection of people that he manages, the people all implement IPerson, but different types of people have different properties. I want to display this manager in a tree, and under the manager node I want to show all the projects he is managing which can be determined from the people he manages.

So the plan is to use a converter to convert a person into a List of projects. Here is the 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>

My Person class implements INotifyPropertyChanged, and the list holding the people implements INotifyCollectionChanged.This code works great when I set the treeview ItemsSource, the Managers are displayed with their list of projects.

However, when I add a new person to the list of people, the TreeView is not updated. When I debug, I can see that the CollectionChanged is firing with the Add action and the added item. Also the CollectionChanged event is not null so I know the UI is watching it. But the Converter does not execute when the item is added.

here is the Add method for the List holding the IPerson objects:

public void Add(T item)
{
    list.Add(item);
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}

Am I somehow breaking the databinding?

What other things can I check for?

The Converter just looks at each item in the People list and figures out what projects they are working on and adds the project name to an output List.

Was it helpful?

Solution

The converter is applied to the property that stores the collection. Therefore, it will only be called if the collection instance itself changes (not if items in the collection are changed). One way around this would be to invalidate the collection when you want it to refresh.

The simplest way to invalidate the collection property and cause the converter code to run again would be to null out the collection and reassign it. Another way is to get the BindingExpression (via BindingOperations) and call UpdateTarget. Finally, you could instead bind to a CollectionView (or subclass thereof) and call Refresh on it.

And if you really want to fix the problem cleanly, you could bind to your own implementation of ICollectionView which does the filtering and raises events as necessary.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top