Binding a CollectionViewSource within a DataTemplate
Asked Answered
Y

3

13

'ContentTemplate' is a DataTemplate that displays an object which has a member 'FooList' (an ObservableCollection).

<DataTemplate x:Key="ContentTemplate">
    <ListBox ItemsSource="{Binding Path=FOO}">
        ...
    </ListBox>
</DataTemplate>

I need to be able to filter that FooList using a CollectionViewSource. This is usually been straight forward but I can't seem to get the binding to work within a DataTemplate. I attempted to this:

<DataTemplate x:Key="ContentTemplate">
    <DataTemplate.Resources>
        <CollectionViewSource x:Key="CVS" Source="{Binding Path=FooList}" Filter="FooFilter"/>
    <DataTemplate.Resources>
    <ListBox ItemsSource="{Binding Source={StaticResource CVS}}">

The errors I get from this is:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FooList; DataItem=null; target element is 'CollectionViewSource' (HashCode=52991666); target property is 'Source' (type 'Object')

Which sounds to me like it's looking for 'FooList' on the CollectionViewSource instead of the object bound to the DataTemplate.

So... how do I get this to look at the correct object?

Yorker answered 28/7, 2010 at 23:24 Comment(2)
I'm having the same problem. Only thing I can think of is that the CVS doesn't know the correct source for the binding (your 'FooList' member) which should be the DataContext at this level. Is there a way to explicitly set the source on the CVS to the current DataContext of the DataTemplate? Again, should be assumed but this isn't working for us both. (The only difference between yours and mine is that you're binding to an internal ListBox. I'm binding to the child items of a HierarchicalDataTemplate for use in a treeview. But other than that, you and I are in the same boat.Frisette
It seems to me that it's not supposed to have access to the Data of the DataTemplate inside the resource part. Does anyone know if that is correct?Corporative
H
32

As I understand it, the DataTemplate acts as instructions on what to insert into the visual tree but does not become a part of the visual tree itself. I only came to this hypothesis after running into the same problem you've described above. I fixed the issue by attaching the CollectionViewSource to the resources of an element that would be part of the visual tree, in my case a grid. Here is the sample that did work:

<DataTemplate DataType="{x:Type TypedLists:AssetModelListViewModel}">
    <Grid>
        <Grid.Resources>
            <CollectionViewSource x:Key="items"
                                  Source="{Binding}">
                <CollectionViewSource.SortDescriptions>
                    <scm:SortDescription PropertyName="AssetType.AssetCategory.Name" />
                    <scm:SortDescription PropertyName="AssetType.Name" />
                    <scm:SortDescription PropertyName="Manufacturer.Name" />
                </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>
        </Grid.Resources>

        <ListView ItemsSource="{Binding Source={StaticResource items}}">

        </ListView>
    </Grid>
</DataTemplate>
Hornsby answered 7/7, 2011 at 17:37 Comment(1)
You're awesome! This fixed the issue I ran into. Thanks!Monsignor
A
0

I worked around this issue by moving the data template into a user control.

Assyriology answered 7/1, 2011 at 17:15 Comment(0)
C
-1

I think you need to bind to the view of the CollectionViewSource:

<ListBox ItemsSource="{Binding Path=View, Source={StaticResource CVS}}">
Cordell answered 14/10, 2010 at 8:28 Comment(2)
Just posted a similar question as well. Tried your solution of explicitly specifying 'View' for the path, but it doesn't work. Also, when you normally bind to a CVS, you don't specify 'View' for the path anyway so I'm not sure what that would have given. Still, I'm not sure why this code doesn't work anyway so there's that too.Frisette
Your code won't work. CollectionViewSource is an XAML proxy to access CollectionView, you doesn't need to specify the Path.Bookcase

© 2022 - 2024 — McMap. All rights reserved.