Mar 23, 2016

How To Allow To Sort By Multiple Columns in Custom Data Binding

Introduction

When you bind DataGridView to a custom business object, you probably want to allow to sort by column or by multiple columns. You are able to use BindingSource to bind your data, but this component does not realize sorting functions.
If you need to sort by one column only, you can use SortableBindingList described in the article: Custom Data Binding, Part 2.
But the technology used here does not allow to sort by multiple columns. This article describes how to add sorting functionality in a simple and fast manner. 

Background

When you want to bind DataGridView to your business logic objects, you typically use three steps:
  1. In design-time: Create specified DataSource type for your object (by selecting Data-Add new data source in the menu and by specifying your custom object as fields source; see Custom Data Binding, Part 1 for more details).
  2. In design-time: Create BindingSource component and specify created DataSource for its DataSource property.
  3. In runtime: Create the list of your specified type and assign it to the DataSource property of the BindingSource component.
In this case, you can't use BindingSource.Sort property because your List<...> will be automatically transformed to the BindingList<...>. To allow sorting by one or multiple columns DataSource should implement IBindingListView interface, but the created BindingList<...>does not implement it (as you can see in the BindinList realization):
public class BindingList<T> : Collection<T>, IBindingList, IList, 
 ICollection, IEnumerable, ICancelAddNew, IRaiseItemChangedEvents
So, we need to implement IBindingListView to be able to sort by one or multiple columns. You can use the Sort property of theBindingSource then by specifying columns names and sort direction and using comma separator, e.g.:
BindingSource.Sort = "Column1 ASC, Column2 DESC, Column 3 ASC"; 
So, I have created MultipleSortableBindingListView class to implement IBindingListView interface:
public class MultipleSortableBindingListView<T> : BindingList<T>, IBindingListView 

Using the Code

Let's imagine, that we have a Person class and list of objects to be displayed on the DataGridView:
public class Person {...} 
public List<Person> list = ...;
Now you should use MultipleSortableBindingListView<Person> instead of List<Person>. As you can see, BindingList (andMultipleSortableBindingListView too) implements IList. Thus, you do not need to change your logic to create the list of Persons to be displayed: our new class has methods as List class.
The next step is to enjoy! Now MultipleSortableBindingListView<...> will be used when BindingSource.DataSource is assigned to a list variable, and you can enjoy with the Sort property of the BindingSource component. It works!

Points of Interest

I have used PropertyComparer class from Custom Data Binding, Part 2, and I have hardly changed it to allow to compare different basic values and reference type properties.

0 comments:

Post a Comment

Nam Le © 2014 - Designed by Templateism.com, Distributed By Templatelib