Click here to Skip to main content
6,305,776 members and growing! (16,871 online)
Email Password   helpLost your password?
Desktop Development » Grid & Data Controls » DataSets, DataGrids etc     Advanced

Sorting DataGrid programmatically

By Alexander Yumashev

This code sorts a Windows.Forms.DataGrid programmatically, "emulating" a header click.
C#.NET 1.0, .NET 1.1, Win2K, WinXP, Win2003VS.NET2003, Dev
Posted:5 Aug 2004
Views:106,944
Bookmarked:34 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
11 votes for this article.
Popularity: 3.28 Rating: 3.15 out of 5
3 votes, 27.3%
1
1 vote, 9.1%
2

3
1 vote, 9.1%
4
6 votes, 54.5%
5

Introduction

This article shows, how to programmatically sort a System.Windows.Forms.DataGrid. In other words, how to emulate a "click" on a column header.

Typically, to sort a DataGrid, we call the DataView.Sort method of an underlying DataView. But what if our DataGrid is bound to a custom datasource? In this case, there's no DataView under our DataGrid!

Background

I was writing an application and the task was to "remember" the way DataGrids are sorted. So I needed to save my sortings to the Windows registry and restore it each time my application starts.

The problem was: my DataGrid was bound to a custom collection, no DataViews or DataTables.

Sorting Basics

If your DataGrid is bound to some IList collection and you want your DataGrid to support sorting - your collection must implement IBindingList interface. This interface contains a method ApplySort() among others. When a user clicks a column header, DataGrid calls the datasource's method ApplySort().

ApplySort() method takes two arguments: property and direction.

void IBindingList.ApplySort(PropertyDescriptor property, 
                                           ListSortDirection direction)

Each column of your DataGrid represents some property of an underlying object. And you have to pass this property to ApplySort() method.

Emulate column header click

I've discovered that simply calling ApplySort() doesn't work. Calling DataGrid's OnMouseDown() protected method with MouseEventArgs pointed to a column header also doesn't work!

So, I used System.Reflection to look deep inside the DataGrid class and see what happens when a user clicks a header. In the list of DataGrid's private members, I've found a private method ColumnHeaderClicked(). See what I mean? Bingo.

This method is defined as follows:

private void ColumnHeaderClicked(PropertyDescriptor prop)

So, if we want to sort column number 5, we have to determine the underlying PropertyDescriptor for this column and pass this PropertyDescriptor to ColumnHeaderClicked method. This can be done in two ways.

  • Calling for a GridColumnStyle.PropertyDescriptor property of a grid column. But this property sometimes returns null if our grid is bound to a custom collection through MappingNames.
  • If our DataGrid is bound to a custom collection MyCollection, we typically create a TableStyle and some GridColumnStyles and assign its MappingNames. TableStyle's MappingName would be "MyCollection" and ColumnStyle's MappingName would contain the name of some property this column displays. So, we can get the PropertyDescriptor object by seeking for the property with the name, equal to the column's MappingName.

After we have a PropertyDescriptor object, we simply invoke a private method using System.Reflection.

Now the code:

public class MyDataGrid : DataGrid
{
 //sort a column by its index

 public void SortColumn(int columnIndex)
 {
  if(this.DataSource!=null && 
    ((System.Collections.IList)this.DataSource).Count>0)
  {
   //discover the TYPE of underlying objects

   Type sourceType = ((System.Collections.IList)this.DataSource)[0].GetType();

   //get the PropertyDescriptor for a sorted column

   //assume TableStyles[0] is used for our datagrid... (change it if necessary)

   System.ComponentModel.PropertyDescriptor pd =
    this.TableStyles[0].GridColumnStyles[columnIndex].PropertyDescriptor;

   //if the above line of code didn't work try to get a propertydescriptor

   // via MappingName

   if(pd == null)
   {
    System.ComponentModel.PropertyDescriptorCollection pdc =
     System.ComponentModel.TypeDescriptor.GetProperties(sourceType);
    pd =
     pdc.Find( this.TableStyles[0].GridColumnStyles[columnIndex].MappingName, 
                                                                      false);
   }

   //now invoke ColumnHeaderClicked method using system.reflection tools

   System.Reflection.MethodInfo mi =
    typeof(System.Windows.Forms.DataGrid).GetMethod("ColumnHeaderClicked",
     System.Reflection.BindingFlags.Instance |
     System.Reflection.BindingFlags.NonPublic);
   mi.Invoke(this, new object[] { pd });
  }
 }
}

That's it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alexander Yumashev


Member
Senior software developer in a financial services company, Moscow, Russia.

Developing C# asp.net applications, winforms applications, databases (SQL Server 2000/2005) etc. etc.
Occupation: Web Developer
Location: Russian Federation Russian Federation

Other popular Grid & Data Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 13 of 13 (Total in Forum: 13) (Refresh)FirstPrevNext
GeneralWindows.Forms.DataGrid.DataSource.DefaultView.Sort Pinmemberpcflasch11:59 28 Mar '07  
GeneralMultiple Sorting on Columns PinmemberRakshitUppal13:22 21 May '06  
GeneralWhy calling private Methods? No need to do that... Pinmemberfex1340:35 7 Oct '05  
GeneralRe: Why calling private Methods? No need to do that... Pinmemberbasskeeper2:34 21 Mar '06  
GeneralWhy is "ApplySort" firing twice? PinmemberChris Simeone7:08 18 May '05  
GeneralAnother way - setting sort order for any DataGrid through Currency Manager private method PinsussAlexander Glebovsky4:29 17 Apr '05  
GeneralRe: Another way - setting sort order for any DataGrid through Currency Manager private method PinsussAnonymous2:51 4 May '05  
GeneralNo need to subclass DataGrid PinsussAnonymous3:54 20 Mar '05  
GeneralNe rabotaet nichego. Property descriptor poluchil normalno. Cho delat ? PinsussAnonymous4:26 1 Nov '04  
GeneralRe: Ne rabotaet nichego. Property descriptor poluchil normalno. Cho delat ? PinsussAnonymous4:28 1 Nov '04  
GeneralTrouble using code PinmemberElNoNo6:22 20 Oct '04  
GeneralRe: Trouble using code PinmemberElNoNo11:45 20 Oct '04  
GeneralMULTIPLE CONTROLS IN A CELL PinmemberPradeep K V1:45 27 Sep '04  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 5 Aug 2004
Editor: Smitha Vijayan
Copyright 2004 by Alexander Yumashev
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project