我只使用一个简单的 DataGridView 来保存一堆数据(有趣的是)。
我在特定列中有小数。但是当按小数列排序时,它的排序是错误的。例如:
起始订单可能是:
结束顺序是:
如您所见,它从第一个数字开始排序。然后就这样下单了。
我想我可以将列设置为不同的“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;
}
}
MSDN 中有对 SortResult 值的描述:
如果第一个单元格将小于零 在第二个单元格之前排序;零 如果第一个单元格和第二个单元格有 等效值;大于零 是否对第二个单元格进行排序 在第一个单元之前。
请注意,在我的测试台中,唯一的数字列是第一个(索引为 0),因此这就是我检查列索引的原因。
此外,根据您的需求和数据,您可能需要优化我的代码 - 例如,如果由于某种原因您的列中有非数字数据,我的代码将引发异常。
您可能已经看过它,但是这里是有关自定义 DataGridView 排序的 MSDN 页面的链接。正如你所说,他们只处理文本。
我也有同样的问题。我尝试使用 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 或其他...... 所以你必须改变数据库中的值类型...... 当您单击列标题时,您无需编写任何代码或直接排序的内容...
它正在按字符排序。您需要使列类型浮点,以便它知道要应用什么比较运算符。
(也就是说,您需要使数据集中的列类型浮动,我相信这会起作用。)
您的问题是
datagridview
按字符串排序。当您将该单元格复制到 string
时,尝试将 float
转换为 datagrid
。
添加Datagridview列标题鼠标点击事件,代码如下:
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex == -1 && e.ColumnIndex >= 0)
{
DataGridViewColumn clickedColumn = dataGridView1.Columns[e.ColumnIndex];
// Check if the clicked column contains float values (adjust the check for your specific column)
if (clickedColumn.Name == "colScore" || clickedColumn.Name == "colID")
{
// Sort using a custom comparer
dataGridView1.Sort(new FloatColumnComparer(e.ColumnIndex));
}
}
}
稍后我们需要添加自定义Comparer来进行排序。这里我们使用了 float 数据类型,这样我们就可以用它来对整数和浮点数进行排序。代码如下:
private class FloatColumnComparer : IComparer
{
private readonly int columnIndex;
private static bool Ascending = true;
public FloatColumnComparer(int columnIndex)
{
this.columnIndex = columnIndex;
Ascending ^= true;
}
public int Compare(object x, object y)
{
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
float value1, value2;
if (float.TryParse(row1.Cells[columnIndex].Value.ToString(), out value1) &&
float.TryParse(row2.Cells[columnIndex].Value.ToString(), out value2))
{
if (Ascending)
return value1.CompareTo(value2);
else
return value2.CompareTo(value1);
}
return 0; // If parsing fails or values are not valid floats, consider them equal.
}
}