XamGrid: Now with Excel Style Filtering

Damyan Petev / Monday, November 28, 2011

The latest release of our NetAdvantage product has been truly feature rich. For 11.2 the XamGrid was made available for WPF and with that it joined the team of XAML Cross-platform controls. But it also received many improvements, one of those is a new exciting feature related with filtering – a Filter Menu.

The main goal is of course much more user friendly filtering interface as many users are familiar with how Excel Filtering works. This new filtering option would not only make users more confortable but it also brings a lot of functionality in terms of what kind of filters can be used and how complicated search can the end-user perform and in this article we will take the time to look into those.

A quick comparison

So far the XamGrid offered only a filter row at its top or bottom. That one is not going away and when enabling filtering you will have to chose which mode to use. So what do you get and loose?

Well, to begin with, the filter row is true to its name and will create and occupy a row of your grid. The Filter Menu is a dropdown and its only permanently visible addition to the layout would be an icon in the column headers. Here’s an illustration how both look:

So by using the menu mode you would save vertical space for one row but as you can see unless instructed otherwise the grid will increase the width of the columns to fit the icon. The filter row does have an advantage too as it would let you see the currently active filter while the changed filter menu’s icon would be the only indication there’s a filter active on that column.

While being shy on space usage, the filter menu doesn’t hold back when providing the user with the best experience is involved. For those unfamiliar with Excel when the icon is clicked a menu appears offering you multiple ways to narrow down large amounts of data with great ease and in the XamGrid it can look like that:

Just as expected it is available for child columns and that is another row of space saved for every level of hierarchy in the data. Being compact is not even the strength of this feature to begin with. An intuitive and inviting UI the menu also provides (as seen above) plenty of extra functionality – it will display a list with all available items and provide the user with a search field and an easy “Select All” checkbox that can be used to quickly add or even remove items. The menu has a handle on the right lower corner that can be dragged to resize it when dealing with lengthy items in large sets to reduce scrolling.

There’s also a special case with dates as the search will kindly provide a dropdown to allow results to match just what you need:

So far you might be asking where did the good old “greater than” and “ends with” filter options go – and not to worry they are all available just under the clear option in a separate menu node or as can be seen as ‘Text/Date Filters’ above.

Filters

As expected from a smart filter menu those would be presented to the user based on the type of data in the column. All will provide the basic Equal/Not Equal options.

Numeric value columns’ filters will offer comparative operands like greater or between:

Mixed content or just text filters will include options like Ends With or Contains:

And the options for a column containing dates are simply overwhelming! Including things like viewing data from today or this week/year, picking a specific month or even a quarter – the list goes on. Click on the thumbnail to see for yourself.

The XamGrid Filter Menu will attempt to provide the user with almost everything needed for a common case scenario filtering at the cost of as few clicks as possible. But when common is not the case…

More complicated filters more readily!

Do note that the option on top of every menu so far states “filters”. What that means is the Filter Menu can provide even better filtering while allowing multiple filters to be active. Imagine hundreds of thousands rows of data and then imagine trying to filter them melts the data down to just under a thousand. Too much? Well luckily you can filter the filter results!

Or the data required can’t be described with a single filter? Two or more simultaneously would do. Here’s a small example begging with a user wishing to view products launched in July.

Receiving the following results:

But also in September. Not a problem one more filtering won’t solve.

Selecting “Add current selection to filter” would combine the current results with the ones matching the new search, essentially combing them in this case or possibly removing unnecessary rows. The results the user gets are just the ones requested:

And when combining filters isn’t easy and fast enough, time and effort can be saved by creating a custom filter of your own. You have the ability to provide the logic (strongly typed lambda expression) used to filter, a name and even icon for your filter and choose if it requires user input or not. Here’s a sample code for filter named “Sweets” that does not require input and returns all rows that have ‘sweet’ in their description. The filter is then added to the filter row (more on that below) and the filter menu when the XamGrid is loaded in the appropriate event.

  1. public class Sweets : FilterOperand
  2. {
  3.     protected override string DefaultDisplayName
  4.     {
  5.         get
  6.         {
  7.             return "Sweets";
  8.         }
  9.     }
  10.  
  11.     public override bool RequiresFilteringInput
  12.     {
  13.         get
  14.         {
  15.             return false;
  16.         }
  17.     }
  18.  
  19.     // Create filter expression that returns all categories that have 'sweet' in their description
  20.     public override System.Linq.Expressions.Expression FilteringExpression (object value)
  21.     {
  22.         System.Linq.Expressions.Expression<Func<Category, bool>> expr = category => category != null && category.Description.ToLower().Contains("sweet");
  23.         return expr;
  24.     }
  25. }
  26.  
  27. private void xamGrid_Loaded(object sender, RoutedEventArgs e)
  28. {
  29.     //Include the filter operand to the row filter used in custom filter dialogs
  30.     FilterColumnSettings filterColSettings = this.xamGrid.Columns.DataColumns["Description"].FilterColumnSettings;
  31.     filterColSettings.RowFilterOperands.Add(new Sweets());
  32.     //Also include it in the dropdown menu:
  33.     var filterMenuOperands = this.xamGrid.Columns.DataColumns["Description"].FilterColumnSettings.FilterMenuOperands;
  34.     FilterMenuTrackingObject filterMenuTrackObj = new FilterMenuTrackingObject(new Sweets());
  35.     filterMenuOperands.ElementAt(0).Children.Add(filterMenuTrackObj);
  36. }

The user will see a new option in the menu and in this example there are only two rows that contain ‘sweet’ and they will be the only ones left right after choosing the option.

If value is required (that is what the value object in the FilteringExpression method is for) it’s worth also considering adding an data template that would serve as icon. Let’s have a filter to perform the standard “Starts With..” but for numbers column. It will require user input which is actually done in separate dialog that feels very similar to the Row filter and can display icons. The icon creation starts with a template (inside some element’s resources) in XAML and will look like Xyz:

  1. <DataTemplate x:Key="BeginsWithIcon">
  2.     <StackPanel>
  3.         <TextBlock FontSize="8">
  4.             <Italic><Underline><Bold>XBold>Underline>Italic>yz
  5.         TextBlock>
  6.     StackPanel>
  7. DataTemplate>

Here’s the class for the filter itself:

  1. public class BeginsWith : FilterOperand
  2. {
  3.     protected override string DefaultDisplayName
  4.     {
  5.         get
  6.         {
  7.             return "Begins with...";
  8.         }
  9.     }
  10.  
  11.     public override bool RequiresFilteringInput
  12.     {
  13.         get
  14.         {
  15.             return true;
  16.         }
  17.     }
  18.  
  19.     //Create filter expression that returns all categories with ID beginning with user-defined sequence
  20.     public override System.Linq.Expressions.Expression FilteringExpression (object value)
  21.     {
  22.         System.Linq.Expressions.Expression<Func<Category, bool>> expr = category => category != null && category.CategoryID.ToString().StartsWith(value.ToString());
  23.         return expr;
  24.     }
  25. }

And the difference here is that we would add it to the CategoryID column and while creating the instance we’ll add the our data template as icon. The code below is an added in the ‘Loaded’ event of the grid:

  1. //Add the 'Begins With' filter
  2. //Include the filter operand to the row filter used in custom filter dialogs
  3. DataTemplate filterIcon = (DataTemplate)this.Resources["BeginsWithIcon"];
  4. filterColSettings = this.xamGrid.Columns.DataColumns["CategoryID"].FilterColumnSettings;
  5. filterColSettings.RowFilterOperands.Add(new BeginsWith() { Icon = filterIcon });
  6. //Also include it in the dropdown menu:
  7. filterMenuOperands = this.xamGrid.Columns.DataColumns["CategoryID"].FilterColumnSettings.FilterMenuOperands;
  8. filterMenuTrackObj = new FilterMenuTrackingObject(new BeginsWith());
  9. filterMenuOperands.ElementAt(0).Children.Add(filterMenuTrackObj);

Why do we add filters to the filter rows when using the Menu? Simple, when the user creates custom filters or is required to provide input a dialog is displayed and it contains exactly the filter rows. When the user clicks here:

This dialog window is displayed:

You can see our icon, the added dummy rows behind and the filter value and it is no wonder the results are as follows:

Conclusion

The XamGrid Filter Menu comes with many benefits. It will appeal to both Excel users and NetAdvantage for WPF XamDataGrid user offering familiar interface. Enhanced user experience that doesn’t sacrifice functionality, quite the contrary – it adds easier ways to get just the relevant data,comes with a lot of predefined options, allows the user to combine filters for greater results and the developer to add and improve it even more.

Try out the live demo on our samples page.

Or download a demo with all mentioned in this article from here.

The demo project has XamGrid with enabled editing and row adding so you can tweak the data to be filtered to your liking and has been cleaned so make sure the references are in place and build.