Yogesh Jagota's Personal Blog
small c# code snippets and free code libraries

Filtering WPF toolkit DataGrid

Saturday, 1 November 2008 20:52 by Yogesh Jagota

As you all know that Microsoft WPF toolkit version 1.0 is now available for download. I was experimenting  with the new datagrid included in the toolkit and found it to be quite good. I searched a little and found three good blog posts about sorting the datagrid. They are:

Improving Microsoft DataGrid CTP sorting performance Part I

Improving Microsoft DataGrid CTP sorting performance Part II

WPF DataGrid: Tri-state Sorting sample

Refering to the above posts will be really useful for anybody who wants to custom sort the datagrid.

Although I was able to find these good posts about sorting, I was not able to find any useful post about filtering the datagrid. After a little search I found a post titled WPF DataGrid sample: Add a preview ToolTip to a ScrollViewer. In this post, Vincent Sibal replied to a comment saying that extended filter is possible using CollectionViewSource. Learning this, I thought of writing the sorting functionality into the datagrid by my own. Initially I was unsuccessful in implementing this functionality as I was using CollectionView, but later I succeeded when I switched to ListCollectionView. I don't know if this a bug but I only tried my implementation with SubSonic and EF collections so CollectionView might not be working with only these two (although I cannot say this with confidence as I did not tried it with any other collection type).

We will be using a textbox's TextChanged method to filter the grid.

Here is how it goes:

First we declare the datagrid:

   1:  <toolkit:DataGrid Name="AreaDataGrid"  Margin="10,0,10,0" 
   2:      IsSynchronizedWithCurrentItem="False" Grid.Row="1" Height="250"
   3:      Width="400" SelectionMode="Extended" AutoGenerateColumns="False"
   4:      CanUserReorderColumns="False" GridLinesVisibility="None"
   5:      AlternationCount="2" CanUserResizeRows="False"
   6:      ItemsSource="{Binding}" >
   7:      <toolkit:DataGrid.Columns>
   8:          <toolkit:DataGridTextColumn Header="Id" Width="80"
   9:              Binding="{Binding Id}"
  10:              IsReadOnly="True"/>
  11:          <toolkit:DataGridTextColumn Header="Name" Width="200" 
  12:              Binding="{Binding Name}"
  13:              IsReadOnly="True"/>
  14:      </toolkit:DataGrid.Columns>
  15:  </toolkit:DataGrid>
  16:  


Then we attach the collection with the datagrid in the Loaded method of the window:

   1:  ListCollectionView dgcv = 
   2:      new ListCollectionView(new AreaCollection().Load());
   3:  dgcv.Filter = SearchFilter;
   4:  
   5:  AreaDataGrid.ItemsSource = dgcv;
   6:  


Now we write the SearchFilter method which actually filters the collection:

   1:  private bool SearchFilter(object sender)
   2:  {
   3:      if (tbSearch == null)
   4:          return true;
   5:  
   6:      // tbSearch is the textbox which contains the
   7:      // text to be filtered...
   8:      string search = tbSearch.Text;
   9:  
  10:      // convert the sent object to Area object...
  11:      Area item = (Area)sender;
  12:  
  13:      if (!search.IsNullOrEmpty())
  14:      {
  15:          if (item.Id.ToString().StartsWith(search) ||
  16:              item.Name.StartsWith(search))
  17:          {
  18:              return true;
  19:          }
  20:  
  21:          return false;
  22:      }
  23:  
  24:      return true;
  25:  }
  26:  


Finally in the TextChanged method of the text box which is used to filter the entries, we use this code:

   1:  ((ListCollectionView)AreaDataGrid.ItemsSource).Refresh();


This is all we need to do. I am not explaining much as most of the code is self explanatory. I tested this way of filtering with 20000 records in the datagrid and found it to be quite fast enough to be used in production scenarios, although it's real test will come when it will be used with more records.

Hope this is helpful to people who need such a functionality to filter the datagrid. I will be posting more about DataGrid soon.

PS: The problem I found with CollectionView was that if I set a breakpoint in the TextChanged method and check the ItemsSource of the datagrid after ((ListCollectionView)AreaDataGrid.ItemsSource).Refresh();, I found that it DID got filtered, but the corresponding changes do not reflect in the datagrid. It still showed all the items in the datagrid. Changing to ListCollectionView sorted out this issue.

Del.icio.usDigg It!DZone It!kick it on DotNetKicks.com
Tags:   ,
Categories:   C# | WPF
Actions:   E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Comments

Add comment


 

biuquote
Loading