C# Winform DatagridView数值列排序

C# Winform DatagridView数值列排序,c#,winforms,datagridview,C#,Winforms,Datagridview,我只使用一个简单的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”,这可能会自动完成。但是没有“数字

我只使用一个简单的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上使用的“排序”方法。但解释有点让我不知所措,示例中没有使用数字,只有文本,所以我看不出我应该如何切换


任何帮助都将不胜感激

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


(也就是说,您需要使数据集中的列类型浮动,我相信这会起作用。)

您可以通过为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;
   }
}
private void dataGridView1\u SortCompare(对象发送方、DataGridViews sortCompareEventArgs e)
{
如果(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())
MSDN中有对SortResult值的描述:

如果第一个单元格将 在第二个单元格之前进行排序;零 如果第一个单元格和第二个单元格 等效值;大于零 如果第二个单元格将被排序 在第一个单元之前

请注意,在我的测试床中,唯一的数字列是第一列(索引为0),因此我对列索引进行了检查

此外,根据您的需要和数据,您可能希望优化我的代码-例如,如果出于某种原因,列中有非数字数据,我的代码将引发异常


您可能已经看到了它,但它是一个指向MSDN页面的链接,介绍如何自定义DataGridView排序。正如您所说,它们只处理文本。

您的问题是
datagridview
是按字符串排序的。当您将
单元格复制到
数据网格中时,请尝试将
字符串
强制转换为
浮点
,我也遇到了同样的问题。我尝试使用David Hall提到的事件处理程序。我在定义DataGridView时使用了ValueType属性。它现在按双倍排序,不需要自定义事件处理程序代码

dataGridView1.Columns[int index].ValueType = typeof(double);
您还可以使用

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

数值类型具有内置的CompareTo函数,该函数可用作SortCompare事件的SortResult

    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的类型。

您的数据库列类型应该是int、double或float,而不是varchar或其他类型。。。。 因此,您必须更改数据库中的值类型。。。
当您点击列标题时,您无需编写任何代码或直接排序的内容…

yikes!你是如何把数据输入网格的?嗯。。。我有一个自定义结构的列表。其中包含大约5个字符串元素。因此,我可以使用forloop,遍历列表,然后将它们逐个添加到datagrid中。通过webscraping实现,一旦数据进入网格,就不需要“保留”数据。没有数据操作(除了排序:P),只是使用datagrid进行查看。如果定义迭代器和属性,则可以将列表绑定到网格。它被称为数据对象(用于谷歌搜索)。如果可行的话,这是一个很好的建议。然而,无论出于什么原因,这对我来说都不起作用。我在调试器中检查了它,ValueType确实被指定为“Double”,但它实际上并没有相应地排序。@Yellow您可能需要检查您是否正在执行
typeof(Double)
而不是
typeof(Double)
。一个是类,另一个是变量类型。我在使用def Double类时也遇到了类似的问题。我一直在努力解决这个问题,你的代码可以正常工作,而我发现的其他代码却不能。谢谢。此外,您可以更改查询,将结果转换为int、double或float。您不需要更改数据库中的类型。