views:

625

answers:

2

In my small WPF project, I have a TabControl with three tabs. On each tab is a ListBox. This project keeps track of groceries we need to buy. (No, it's not homework, it's for my wife.) So I have a list of ShoppingListItems, each of which has a Name and a Needed property: true when we need the item, and false after we buy it.

So the three tabs are All, Bought, and Needed. They should all point to the same ShoppingListItemCollection (which inherits from ObservableCollection<ShoppingListItem>). But Bought should only show the items where Needed is false, and Needed should only show items where Needed is true. (The All tab has checkboxes on the items.)

This doesn't seem that hard, but after a couple hours, I'm no closer to figuring this out. It seems like a CollectionView or CollectionViewSource is what I need, but I can't get anything to happen; I check and uncheck the boxes on the All tab, and the items on the other two tabs just sit there staring at me.

Any ideas?

A: 

Here are a couple of ideas:

  1. When tabs Bought and Needed load, filter them yourself by creating new collections with the items you want, or
  2. when tabs Bought and Needed load, override the list item databind and toggle visability based on Needed
steve
+3  A: 

You can use a CollectionViewSource to reuse the original collection with a filter.

<Window.Resources>
    <CollectionViewSource x:Key="NeededItems" Source="{Binding Items}" Filter="NeededCollectionViewSource_Filter" />
    <CollectionViewSource x:Key="BoughtItems" Source="{Binding Items}" Filter="BoughtCollectionViewSource_Filter" />
</Window.Resources>

<TabControl>
    <TabItem Header="All">
        <ListBox DisplayMemberPath="Name" ItemsSource="{Binding Items}" />
    </TabItem>
    <TabItem Header="Bought">
        <ListBox DisplayMemberPath="Name" ItemsSource="{Binding Source={StaticResource BoughtItems}}" />
    </TabItem>
    <TabItem Header="Needed">
        <ListBox DisplayMemberPath="Name" ItemsSource="{Binding Source={StaticResource NeededItems}}" />
    </TabItem>
</TabControl>

Some code behind is required for the filter.

private void NeededCollectionViewSource_Filter(object sender, FilterEventArgs e)
{
    e.Accepted = ((ShoppingListItem) e.Item).Needed;
}

private void BoughtCollectionViewSource_Filter(object sender, FilterEventArgs e)
{
    e.Accepted = !((ShoppingListItem) e.Item).Needed;
}
Todd White