开发者

WPF - CollectionViewSource Filter Not Working

I have acquired a control which allows selection of multiple items from the codeproject article http://www.codeproject.com/KB/WPF/MultipleSelectionControl.aspx. Basically it has 2 listboxes. One starts with all items and when user selects some of them, they move to other listbox. Control defines two dependency properties for the two lists and the one that initially contains all items is AvailableItems. It is used in control's ControlTemplate as follows:

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

I use the control in my project as:

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

I am trying to filter AvailableItems by binding it to a CollectionViewSource and defining a filter function called Data_Filter. AllItems is a List object and it contains strings. When control is initialized, Data_Filter is called for every item in AllItems开发者_开发知识库 and accepted property of FilterEventArgs is set correctly for each item. However, control shows all of the items disregarding the Data_Filter. In control's implementation an ICollectionView object is defined as:

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

which makes me suspicious that the control is skipping my view. I can try to implement filtering in control's implementation but this is not a good solution. Any suggestions?


If I'm reading your code snippets correctly, yes, your collection view is never being used; GetDefaultView does not return any views that were explicitly created by a CollectionViewSource.

It looks like the control needs to be refactored to offer an AvailableItemsSource property which would allow you to specify a filtered collection view. The internal logic should then use the items source before creating a default view.

UPDATE

Here's something that you could try:

Define a view model that exposes the collection of available items which can be bound to in the view. The view model will now be responsible for filtering the default collection view. You'll have to decide how to trigger the filtering, i.e., through commands, or property setters, etc., but for the sake of this example, I'll show setting up filter in the view model's constructor:

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

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

The reason why this should work is that CollectionViewSource.GetDefaultView(...) always returns the same view. Thus, if the control is always asking for the default view and your view model has added a filter to it, you should get the desired effect without explicitly creating a CollectionViewSource in XAML.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜