sushi7777
sushi7777

Reputation: 189

Binding to a filtered observable collection

I have an observable collection of type A.

Class A contains an enum - IsWhite.

My observable collection is called ACollection.

I also have 2 datagrids, one that will have an itemssource bound to ACollection where the A items have IsWhite set to false, the other datagrid which is bound to the same collection but with IsWhite set to true.

How can I achieve this?

The collection is declared as follows;

ObservableCollection<A> ACollection = new ObservableCollection<A>;

and the class

public class A
{
    IsWhite isWhiteEnum { get; set; } = IsWhite.False;
}

I want one datagrid itemssource to bind to ACollection populating the items where IsWhite is False and the other datagrid itemssource to bind to ACollection popualting items where IsWhite is True.

Upvotes: 1

Views: 1725

Answers (1)

Andy
Andy

Reputation: 12276

Here's a precis of the relevent parts of the article here:

https://social.technet.microsoft.com/wiki/contents/articles/26673.wpf-collectionview-tips.aspx

You don't want to filter the default view of a collection because that way your filter would apply to both datagrids.

This bit of code gets two independent views:

PeopleView = (CollectionView)new CollectionViewSource { Source = People }.View;
LevelsPeopleView = (CollectionView)new CollectionViewSource { Source = People }.View;

People is an observablecollection of person.

Both those views are collectionviews, eg.

 public CollectionView LevelsPeopleView { get; set; }

The views are bound in TwoCollectionViews.xaml eg

    <DataGrid ....
              ItemsSource="{Binding PeopleView}"

And the article illustrates various filters such as the msdn approach:

private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e)
{
AuctionItem product = e.Item as AuctionItem;
if (product != null)
{
    // Filter out products with price 25 or above
    if (product.CurrentPrice < 25)
    {
        e.Accepted = true;
    }
    else
    {
        e.Accepted = false;
    }
}
}

Or much more sophisticated approaches.

You set a filter:

            LevelsPeopleView.Filter = FirstOfLevel_Filter;

If the view has already grabbed the data out that collectionview then nothing will happen. You need to also do

         LevelsPeopleView.Refresh();

This sort of filtering is quite inefficient and linq is better at large datasets. Still better is small datasets. Unless your users really really like scrolling.

Upvotes: 2

Related Questions