Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Winform DatagridView Numeric Column Sorting

I am using just a simple DataGridView to hold a bunch of data (Funny that).

I have decimals in a particular column. But when it comes to ordering by that decimal column, it orders it incorrectly. For example :

Starting order might be :

  • 0.56
  • 3.45
  • 500.89
  • 20078.90
  • 1.56
  • 100.29
  • 2.39

The ending order would be :

  • 0.56
  • 100.29
  • 1.56
  • 20078.90
  • 2.39
  • 3.45
  • 500.89

As you can see, it orders it starting from the first number. And then orders it in this way.

I thought possibly I could set the column to a different "ColumnType" and that may automatically do it. But there is no "Numeric" or "Decimal" column types.

I was on MSDN looking up the issue, and I could find the "sort" method that I can use on the DataGridView. But the explanation was a bit over my head, and the examples didn't use numbers, only text so I couldnt see how I was supposed to switch things up.

Any help would be much appreciated.

like image 614
MindingData Avatar asked Jan 07 '10 04:01

MindingData


3 Answers

You can solve this by adding a handler for the SortCompare event on the DataGridView with the following code:

private void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
{
    if (e.Column.Index == 0)
    {
        if (double.Parse(e.CellValue1.ToString()) > double.Parse(e.CellValue2.ToString()))
        {
            e.SortResult = 1;
        }
        else if (double.Parse(e.CellValue1.ToString()) < double.Parse(e.CellValue2.ToString()))
        {
            e.SortResult = -1;
        }             
        else
        {
            e.SortResult = 0;
        }
        e.Handled = true;
   }
}

From MSDN there is this description of the SortResult values:

Less than zero if the first cell will be sorted before the second cell; zero if the first cell and second cell have equivalent values; greater than zero if the second cell will be sorted before the first cell.

Note that in my test bed the only numeric column was the first (with index 0) so that is why I have the check on the column index.

Also, depending on your needs and data you may want to refine my code - for example, my code will throw an exception if for some reason you have non numeric data in your column.

You have probably seen it, but here is a link to the MSDN page on customising the DataGridView sorting. As you say, they only deal with text.

like image 178
David Hall Avatar answered Oct 05 '22 23:10

David Hall


I had the same problem. I tried using the event handler as David Hall mentioned. I used the ValueType property when defining the DataGridView. It now sorts as doubles, no custom event handler code needed

dataGridView1.Columns[int index].ValueType = typeof(double);

You can also format the column using

dataGridView2.Columns[int index].DefaultCellStyle.Format = string format;
like image 36
Kevin Jablonski Avatar answered Oct 06 '22 01:10

Kevin Jablonski


Numeric types have a built in CompareTo function, which can be used as the SortResult of the SortCompare event.

    private void dataGridView_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
    {
        if (e.Column.Index == 0)
        {
            e.SortResult = int.Parse(e.CellValue1.ToString()).CompareTo(int.Parse(e.CellValue2.ToString()));
            e.Handled = true;
        }
    }

This is of course assuming you know the type that was put into the DataGridView to begin with.

like image 25
Softerware Avatar answered Oct 05 '22 23:10

Softerware