#986 – Filtering a ListBox Using a CollectionViewSource

When populating a ListBox from a CollectionViewSource, you can also filter the data.  Below is an example of a ListBox that is bound to a CollectionViewSource.

        <CollectionViewSource x:Key="cvsActors" Source="{Binding ActorList}" >
                <scm:SortDescription PropertyName="LastName" />

        <ListBox Name="lbActors" Margin="15" Width="200" Height="200"
                 ItemsSource="{Binding Source={StaticResource cvsActors}}"/>
        <CheckBox Content="Only Joans" IsChecked="{Binding OnlyJoans}"

In code, we add a handler for the Filter event of the CollectionViewSource.  The handler is called for each item in the list.

            // Requires: using System.Windows.Data
            ((CollectionViewSource)this.Resources["cvsActors"]).Filter += ActorList_Filter;

In the handler, we set the Accepted property of the argument if the item should be included in the list.

        void ActorList_Filter(object sender, FilterEventArgs e)
            // Set e.Accepted to true to include the item in the list
            if (!onlyJoans)
                e.Accepted = true;
                Actor a = e.Item as Actor;
                e.Accepted = (a.FirstName == "Joan") ? true : false;


We also have to make sure to “refresh” the CollectionViewSource when the OnlyJoans property changes.  This will trigger it to re-filter the collection.

        private bool onlyJoans;
        public bool OnlyJoans
            get { return onlyJoans; }
                if (value != onlyJoans)
                    onlyJoans = value;