Fun with CollectionViews


Url: http://wilderminds.blob.core.windows.net/downloads/CollectionViewF...

Silverlight LogoI've recently been looking at the PagedCollectionView class. For those who are not familiar with this class, it allows you to automatically show sections of a collection in a paged way (especially when paired with the PagerControl). There is a good example on MSDN here:

http://msdn.microsoft.com/en-us/library/system.windows.data.pagedcollectionview(VS.95).aspx

The PagedCollectionView class supports the ICollectionView interface that supports a number of features that are really useful for dealing with collections.  These include:

  • Sorting
  • Filtering
  • Grouping

To show this, I decided to start with a simple DataGrid.  I created the PagedCollectionView and wrapped my data collection in it like so (GameList is a simple collection of a Game class to show some data):

PagedCollectionView view = 
  new PagedCollectionView(new GameList());

Then when data binding, I simple do the binding directly to the view instead of the collection:

theGrid.ItemsSource = view;

Using the PagedCollectionView as a wrapper for your collection provides the functionality of sorting, grouping and filtering to your collection. Let's start with sorting. 

The ICollectionView interface has a SortDescriptions collection that is used to set the sort for the view. For example, to sort our collection by ReleaseDate then Name, we can add two SortDescription objects to the collection:

view.SortDescriptions.Clear();

view.SortDescriptions.Add(
  new SortDescription("ReleaseDate", 
                      ListSortDirection.Descending));

view.SortDescriptions.Add(
  new SortDescription("ProductName", 
                      ListSortDirection.Ascending));

In our DataGrid, both columns will mark themselves with the sort markers to indicate the search. You can reverse this if you need to detect the changes in sorting that happens when the user clicks on the columns to sort.  You can do this by registering for the CollectionChanged event and looking at the SortDescription collection:

view.CollectionChanged += view_CollectionChanged;

...

void view_CollectionChanged(object sender, 
  NotifyCollectionChangedEventArgs e)
{
  foreach (var s in view.SortDescriptions)
  {
    MessageBox.Show(
      string.Concat("Sorting is: ", 
                    s.PropertyName, 
                    " - ", 
                    s.Direction));
  }
}

The ICollectionView also exposes the ability to group items in the DataGrid. To add grouping, you simply need to add new GroupDescription objects to the view's GroupDescription list. The only type of GroupDescription that is currently implemented is the PropertyGroupDescription which allows you to group by a property. For example, to group by the ReleaseDate I added a new PropertyGroupDescription like so:

view.GroupDescriptions.Add(
  new PropertyGroupDescription("ReleaseDate"));

In the DataGrid, these groups look like so:

Grouping

The last feature I love about the ICollectionView interface is the ability to do arbitrary filtering. The interface has a Filter property that takes a Predicate<object> object.  This way we can use a simple lambda to perform filtering.  For example, to only show the games that have Microsoft in the name, I just create a simple lambda like so:

view.Filter = g => 
  ((Game)g).Publisher.Contains("Microsoft");

Cool, huh?



Shawn
Shawn Wildermuth
Author, Teacher, and Coach




My Courses

Wilder Minds Training
Vue.js by Example (New Lower Price)
Bootstrap 4 by Example (New Lower Price)
Intro to Font Awesome 5 (Free Course)
Pluralsight
Building an API with ASP.NET Core (New Course)
Building a Web App with ASP.NET Core, MVC6, EF Core, Bootstrap and Angular (updated for 2.2)
Less: Getting Started (New)
Using Visual Studio Code for ASP.NET Core Projects
Implementing ASP.NET Web API

Application Name WilderBlog Environment Name Production
Application Ver v4.0.30319 Runtime Framework x86
App Path D:\home\site\wwwroot\ Runtime Version .NET Core 4.6.27817.01
Operating System Microsoft Windows 10.0.14393 Runtime Arch X86