| Comments

The other day I wrote a simple little Silverlight application using a DataGrid to help navigate the TechEd DVD contents.  My code was admittedly quick and dirty.  I loaded up some data, and based on some events re-filtered and re-bound that data.  After thinking about it I am not sure why I didn’t just use some existing controls to help me do that work.  I found that AutoCompleteBox from the new Silverlight Toolkit would do this for me.

One thing that the AutoCompleteBox does quickly is provide filtering for simple string data.  But what about custom types?  My data in the TechEd application has a List<TechEdSession> where TechEdSession is respresented as such:

   1: public class TechEdSession
   2: {
   3:     public string DiscNumber { get; set; }
   4:     public string SessionCode { get; set; }
   5:     public string Track { get; set; }
   6:     public string SessionTitle { get; set; }
   7:     public string Speakers { get; set; }
   8:     public string TechEdConf { get; set; }
   9: }

If you wire up the AutoCompleteBox.ItemsSource to my List<> nothing will happen.  Why?  Well the control doesn’t know how to understand the data exactly.  So we have to help it.  It knows the data is there but doesn’t know what to return based on the filter.

This is simply done using the ItemFilter property on the control.  We can easily provide a Lambda expression to help the control understand the filter.  After setting the ItemsSource property to the results of my LINQ query, I add the expression to help the control understand the data:

   1: SessionFilter.ItemsSource = sessions;
   2: SessionFilter.ItemFilter = (search, item) =>
   3:     {
   4:         TechEdSession session = item as TechEdSession;
   5:         if (session != null)
   6:         {
   7:             string filter = search.ToLower();
   8:             return ((session.SessionCode.ToLower().Contains(filter) || 
   9:                 session.SessionTitle.ToLower().Contains(filter) || 
  10:                 session.Speakers.ToLower().Contains(filter)) &&
  11:                 session.TechEdConf.ToLower().Contains(((ComboBoxItem)ConfSelector.SelectedItem).Content.ToString().ToLower()));
  12:         }
  13:  
  14:         return false;
  15:     };

That’s it.  I’ve now defined the filter for the control so as the user types data it does the appropriate filtering logic and displays the results.  I’ve chosen to still display the results as a DataGrid for easy reading in this application, but could have also used an ItemTemplate if I desired.  The ItemFilter expects a search predicate to be passed to it.

So the resulting application has the same capabilities, but a lot less code for me to write.  Here’s the ending result:

So if you need to implement AutoCompleteBox and have it search/filter your custom types, be sure to supply your own ItemFilter to help the control know where to look!

Please enjoy some of these other recent posts...

Comments