Home > C#, MVVM, WPF > CompositeCollection Binding Problem – It’s not part of the Visual Tree

CompositeCollection Binding Problem – It’s not part of the Visual Tree


XAML is fantastic, but occasionally unpredictable which can cause some confusion.

One instance of this is the CompositeCollection tag which is used to build up a collection of values from a number of sources.

An example of this might be as simple as adding a “Please choose…” to the top of a drop down list or more complex scenarios, such as building up a list of products from different suppliers. In most cases, when using MVVM these kind of situations can be handled in the View Model, but even so, it can still be useful to build up lists in the XAML.

One such example I hit recently was creating a context menu for filtering on a data grid. I wanted to filter based on the values in the column, but also add two sorting options at the top of the list. A simplified version of the XAML is shown in Listing 1 below.

<ContextMenu.ItemsSource>
    <CompositeCollection>
        <MenuItem Header="Sort Ascending" />
        <MenuItem Header="Sort Descending" />
        <Separator />
        <CollectionContainer Collection="{Binding Path=FilterOptions}}" />
    </CompositeCollection>
</ContextMenu.ItemsSource>

Listing 1 – Simplified code to show an example usage of CompositeCollection

However if you try to use code such as this you’ll very quickly hit the following binding problem.

Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FilterOptions; DataItem=null; target element is ‘CollectionContainer’ (HashCode=23627591); target property is ‘Collection’ (type ‘IEnumerable’)

Why? Well it is all down to the fact that the data context of the XAML, specified at the top level that is inherited down through the elements actually goes down the Visual Tree. The killer is that the CompositeCollection, having no visual properties, is not part of the visual tree and therefore does not inherit the data context. The CompositeCollection has no clue what “FilterOptions” is in this example and thus throws a binding error.

Luckily we can easily solve this as all elements have access to the static resources of the XAML so we can easily create a bridging static resource that does the binding that we need and then use that within the composite collection. Listing 2 shows the static resource that we need in this instance.

<Window.Resources>
    <CollectionViewSource x:Key="FilterOptionsBridge" Source="{Binding Path=Filters}" />
</Window.Resources>

Listing 2 – Static resource bridging back to the data context

And finally we can adjust our CollectionContainer to point to the static resource, as in Listing 3.

...
<CollectionContainer Collection="{Binding Source={StaticResource FilterOptionsBridge}}" />
...

Listing 3 – Update to reference the static resource

As a side note, the CollectionViewSource tag needs to bind to an IEnumerable, so if you are binding to a CollectionView or one of the derived classes you’ll need to change the binding to be to the SourceCollection property as shown in Listing 4.

<Window.Resources>
    <CollectionViewSource x:Key="FilterOptionsBridge" Source="{Binding Path=Filters.SourceCollection}" />
</Window.Resources>

Listing 4 – Updated binding to reference the SourceCollection

Advertisements
  1. February 21, 2012 at 12:08 am
    • galenus
      September 2, 2012 at 9:37 am

      You’ve completely missed the point of this post, based on the link you provide. This one is to solve the problem of binding an element which is not a part of the visual tree, not the limitations of the CompositeCollection.
      -1 for the comment.

  2. November 6, 2012 at 5:54 pm

    You absolute made my day with this post! IT SOLVED MY PROBLEM! Thanks!

  3. Andrew Sheshko
    November 1, 2013 at 10:28 am

    This is what I’ve been looking for. Thanks a lot!

  4. Random
    July 10, 2014 at 3:31 am

    I’m working to solve this problem in a situation where the CompositeCollection is being implemented within a nested MenuItem defined by a style. The IEnumerable that would populate the CollectionContainer doesn’t have a resource I can refer to.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: