views:

1100

answers:

1

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.

+1  A: 

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.

HTH, Kent

Kent Boogaart
I think understand what your telling me to do, but I'm not sure how to do that with the hierarcicalDataTemplate. If I understand correctly, I want to wrap the People Property in a CollectionView, and refresh the CollectionView when the Collection changes. Some example code would be a big help.
Kelly
Thanks for the help, I got it working by wrapping my people list in an ObservableCollection of projects that subscribed to the people collection changed event and updated itself.
Kelly