Sunday, October 21, 2007

How to filter ItemsControl View, rather then Data Source

How to filter data source of ItemsControl, you, probably, know, but what to do, when you want to filter view of the control's items, rather then the data behind? What's the strange requirement, you'll ask. I'll give you very simple example for business case, when you need to filter only what you are viewing in ListBox or any other items control, rather then data behind. You have two listboxes bounded to the same data source. In one, and only one, of those listboxes you want to filter data. What to do?

image

If  you'll filter data by using CollectionViewSource.GetDefaultView(YourListBox.ItemsSource).Filter = new Predicate(FilterOdds) statement or, even YourListBox.Items.Filter = new Predicate(FilterOdds) statement, you'll filter data in both ListBoxes. This is not what you want. You need to filter the view of the data and not a data itself.

Just enumerate listbox items and Collapse "unnecessaries", according predefined criteria. Like following:

for (int i = 0; i < MyListBox.Items.Count; i++)
{
  ListBoxItem itm = MyListBox.Items[i] as ListBoxItem;
   if (FilterOdds(itm.Content))
    MyListBox.Items[i].Visibility = Visibility.Collapsed;
}

image

But, if you want to be even more precise, pay attention on what has been virtualized and what has not by getting underlying VirtualizingStackPanel and enumerating and operating it's items. How to do it? Get and see in source code for this article.

1 comment:

4ndi said...

great great post! i was having struggles with TreeViewItem filters in silverlight. now you've cleared up my confusion! thank you again! great work, keep it up!