WPF - CollectionViewSource过滤器不起作用

时间:2011-08-28 01:24:42

标签: .net wpf collectionviewsource

我已经获得了一个控件,允许从代码项目文章http://www.codeproject.com/KB/WPF/MultipleSelectionControl.aspx中选择多个项目。基本上它有2个列表框。一个从所有项目开始,当用户选择其中一些项目时,它们会移动到其他列表框。 Control为两个列表定义了两个依赖项属性,最初包含所有项目的属性是AvailableItems。它在控件的ControlTemplate中使用如下:

<ListBox
  Grid.Row="2"
  Grid.Column="0"
  SelectionMode="Extended"
  x:Name="PART_AvailableListBox"
  ItemsSource="{Binding AvailableItems}"
  ItemTemplate="{TemplateBinding ObjectsTemplate}">
  <ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
      <EventSetter Event="MouseDoubleClick" Handler="AvailableListBoxItem_DoubleClick" />
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

我在项目中使用控件:

<Window.Resources>
  <CollectionViewSource x:Key="multiSelectDataView" Source="{Binding ElementName=DocumentRoot, Path=AllItems}" Filter="Data_Filter" />
</Window.Resources>

<UI:MultiSelectControl
  x:Name="multiSelect"
  Style="{StaticResource MultiSelectControlStyle}"
  CurrentTitle="Group Components"
  AvailableTitle="All Components"
  AvailableItems="{Binding Source={StaticResource multiSelectDataView}}"
  CurrentItems="{Binding SelectedItems, Mode=TwoWay}">
    <UI:MultiSelectControl.ObjectsTemplate>
      <DataTemplate>
        <TextBlock Text="{Binding}" />
      </DataTemplate>
    </UI:MultiSelectControl.ObjectsTemplate>
</UI:MultiSelectControl>

我试图通过将AvailableItems绑定到CollectionViewSource并定义名为Data_Filter的过滤器函数来过滤它。 AllItems是一个List对象,它包含字符串。初始化控件时,将为AllItems中的每个项调用Data_Filter,并为每个项正确设置FilterEventArgs的接受属性。但是,控件显示忽略Data_Filter的所有项目。在控件的实现中,ICollectionView对象定义为:

this.AvailableItemsCollectionView = 
                CollectionViewSource.GetDefaultView(this.AvailableItems);

让我怀疑控件正在跳过我的观点。我可以尝试在控件的实现中实现过滤,但这不是一个好的解决方案。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

如果我正确读取您的代码片段,是的,您的集合视图永远不会被使用; GetDefaultView不会返回由CollectionViewSource显式创建的任何视图。

看起来控件需要重构才能提供AvailableItemsSource属性,允许您指定过滤后的集合视图。然后,在创建默认视图之前,内部逻辑应使用项目源。

<强>更新

这是你可以尝试的东西:

定义一个视图模型,该模型公开可以在视图中绑定的可用项的集合。视图模型现在将负责过滤默认集合视图。你必须决定如何触发过滤,即通过命令或属性设置器等,但是为了这个例子,我将在视图模型的构造函数中显示设置过滤器:

public class MyViewModel
{
  public IList MyAvailableItems {...}

  public MyViewModel()
  {
    var defaultView = CollectionViewSource.GetDefaultView(MyAvailableItems);
    defaultView.Filter = ...
  } 
}

这应该起作用的原因是CollectionViewSource.GetDefaultView(...)总是返回相同的视图。因此,如果控件始终要求使用默认视图,并且视图模型已向其添加了过滤器,则应在XAML中未明确创建CollectionViewSource的情况下获得所需的效果。