2010-01-07 120 views
7

我正在使用一个简单的DataGridView来保存一堆数据(有趣的是)。Winform DatagridView数字列排序

我在特定列中有小数。但是,当涉及到按小数列排序时,它会错误地命令它。例如:

发车顺序可能是:

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

结局顺序将是:

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

如你所见,它从第一个数字开始下令。然后以这种方式命令它。

我想我可能会将列设置为不同的“ColumnType”,并可能自动执行此操作。但是没有“数字”或“小数”列类型。

我在MSDN上查找问题,我可以找到“排序”方法,我可以在DataGridView上使用。但是这个解释有些凌驾于我的头上,而且这些例子并没有使用数字,只有文字,所以我无法看到我应该如何切换。

任何帮助将不胜感激。

回答

7

您可以通过添加与下面的代码在DataGridView的SortCompare事件的处理程序解决这个问题:

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; 
    } 
} 

从MSDN存在SortResult值的这样的描述:

小于零,如果所述第一小区将 第二CE之前进行排序二;如果第一个单元格和第二个单元格具有相同的值,则表示为 ;如果第二个单元在第一个单元之前将被排序 ,那么大于零 。

请注意,在我的测试床上唯一的数字列是第一个(索引为0),所以这就是为什么我有检查列索引。

此外,根据您的需要和数据,您可能需要优化我的代码 - 例如,如果您的列中存在非数字数据,我的代码将抛出异常。

您可能已经看到它,但here是定制DataGridView排序的MSDN页面的链接。正如你所说,他们只处理文本。

+0

哦,这个男人! 是的工作完美:)谢谢你! – MindingData 2010-01-07 06:41:13

+0

一直在努力,你的代码工作,而我发现的其他人没有。谢谢。 – user1500403 2015-08-05 00:05:58

0

它按字符排序。您需要使列类型为float,以便知道要应用哪个比较运算符。

(也就是你需要列类型数据集中的浮动,我相信会奏效。)

+0

不使用数据绑定:)。 – MindingData 2010-01-07 06:34:13

+0

yikes!你如何获得数据到网格? – Hogan 2010-01-07 14:34:49

+0

那么...我有一个自定义结构的列表。它包含大约5个字符串元素。 因此,我可以使用forloop,遍历列表,并将它们逐个添加到数据网格中。 通过网页浏览做到这一点,并且在数据进入网格后不需要“保留”数据。没有数据操作(除了排序:P),只是使用datagrid进行查看。 – MindingData 2010-01-07 22:21:47

0

你的问题是datagridview正在按字符串排序。尝试将string复制到float,然后将该单元复制到datagrid

6

我有同样的问题。我尝试使用大卫霍尔提到的事件处理程序。定义DataGridView时我使用了ValueType属性。现在排序双打,没有自定义事件处理程序代码需要

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

您也可以格式化使用

dataGridView2.Columns[int index].DefaultCellStyle.Format = string format; 
+0

非常好的建议,如果它能工作。然而,无论出于何种原因,对我而言这是行不通的。我在Debugger中检查过它,ValueType确实是'Double',但实际上并没有进行相应的排序。 – Yellow 2013-09-20 15:05:12

+0

@Yellow您可能想要检查您是否正在执行'typeof(double)'而不是'typeof(Double)'。一个是类,另一个是变量类型。在使用类def Double时,我遇到了类似的问题。 – 2013-10-28 14:40:09

1

数值类型有一个内置的CompareTo功能之列,这可以作为的SortResult SortCompare事件。

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; 
     } 
    } 

这当然假设您知道放入DataGridView中的类型以开始。

1

您的数据库列类型应该是int或double或float,而不是varchar或其他东西.... 因此,您必须更改数据库中的值类型... 您无需编写任何代码或其他东西它直接排序当你点击列头...

+0

此外,您可以更改查询以将结果转换为int,double或float。您不需要更改数据库中的类型。 – 2017-12-06 16:15:37