Posted in:

The first Windows Forms application I ever wrote was an anagram generator back in 2002. As part of my ongoing efforts to learn WPF and M-V-VM, I have been porting it to WPF, and adding a few new features along the way. Today, I wanted to add a TextBox that would allow you filter the anagram results to only show results that contained a specific sub-string.

The first task is to create a TextBox and a ListBox in XAML and set their binding properties. We want the filter to update every time a user types a character in, so we use the UpdateSourceTrigger to specify this.

<TextBox Margin="5" 
     Text="{Binding Path=Filter, UpdateSourceTrigger=PropertyChanged}" 
     Width="150" />
...
<ListBox Margin="5" ItemsSource="{Binding Phrases}" />

Now we need to create the corresponding Filter and Phrases properties in our ViewModel. Then we need to get an ICollectionView based on our ObservableCollection of phrases. Once we have done this, we can attach a delegate to it that will perform our filtering. The final step is to call Refresh on the view whenever the user changes the filter box.

private ICollectionView phrasesView;
private string filter;

public ObservableCollection<string> Phrases { get; private set; }

public AnagramViewModel()
{
   ...
   Phrases = new ObservableCollection<string>();
   phrasesView = CollectionViewSource.GetDefaultView(Phrases);
   phrasesView.Filter = o => String.IsNullOrEmpty(Filter) ? true : ((string)o).Contains(Filter); 
}

public string Filter 
{
   get
   {
      return filter;
   }
   set
   {
      if (value != filter)
      {
         filter = value;
         phrasesView.Refresh();
         RaisePropertyChanged("Filter");
      }
   }
}

And that's all there is to it. It can be kept nicely encapsulated within the ViewModel without the need for any code-behind in the view.

List filtering in WPF

Comments

Comment by Faye

How do you get the listbox to refresh? I put the code in like you have and I see that it is filtering but doesnt show the new data?

Comment by Faye

How does the listbox get refreshed. I have it where I see that the data is filtered but it doesnt display the new filtered data?

Comment by Mark H

see the code fragment above: phrasesView.Refresh

Comment by Sander

Very useful for my project. Thank you!

Sander
Comment by Tammar

Great article!!

Tammar
Comment by Giulio

This is wrong: you need to bind to the ICollectionView and not to the ObservableCollection to see the filtering effect.

Giulio
Comment by xmichael911

This doesn't work

xmichael911