在DataTemplate中绑定CollectionViewSource

时间:2010-07-28 23:24:52

标签: wpf data-binding datatemplate collectionviewsource

'ContentTemplate'是一个DataTemplate,它显示一个具有成员'FooList'的对象(ObservableCollection)。

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

我需要能够使用CollectionViewSource过滤该FooList。这通常是直截了当的,但我似乎无法使绑定在DataTemplate中工作。我试图这样做:

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

我从中得到的错误是:

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= FooList;的DataItem = NULL; target元素是'CollectionViewSource'(HashCode = 52991666); target属性为'Source'(类型'Object')

听起来像是在寻找CollectionViewSource上的'FooList',而不是绑定到DataTemplate的对象。

那么......我怎样才能看到正确的物体?

3 个答案:

答案 0 :(得分:24)

据我所知,DataTemplate充当了插入可视树的内容的指令,但不会成为可视树本身的一部分。我遇到了你上面描述的同样的问题,我才得出这个假设。我修复了这个问题,方法是将CollectionViewSource附加到一个元素的资源中,该元素将成为可视树的一部分,在我的例子中是一个网格。以下是有效的示例:

<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>

答案 1 :(得分:0)

我认为你需要绑定到CollectionViewSource

的视图
<ListBox ItemsSource="{Binding Path=View, Source={StaticResource CVS}}">

答案 2 :(得分:0)

我通过将数据模板移动到用户控件来解决此问题。