为何System.Collections.IComparer处理DataGridView空单元格时不符合预期?
DataGridView按指定规则排序的问题修正(c_seq列:正数升序,null/0/负数排底部)
我有一个名为dg的DataGridView,需要按c_seq列的数值排序,规则是:null、零或负数排在列表底部,其余正数按升序排列,但现有代码实现的结果不符合预期。
现有调用代码:
dg.Sort(New ComparadorLinhas(SortOrder.Ascending))
原代码的问题
- 仅判断
valor1的状态,未兼顾valor2的状态,导致排序逻辑缺失关键分支(比如valor2也是无效值、或valor1是正数但valor2是无效值的场景) - 使用
Shared修饰的modificador_ordem,会导致多个比较器实例互相干扰(Shared变量是类级别,不属于单个实例)
修正后的比较器代码
Public Class ComparadorLinhas Implements IComparer ' 改为实例变量,避免多实例排序方向冲突 Private modificador_ordem As Integer = 1 Public Sub New(ByVal ordem As SortOrder) modificador_ordem = If(ordem = SortOrder.Descending, -1, 1) End Sub Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare Dim linha1 As DataGridViewRow = CType(x, DataGridViewRow) Dim linha2 As DataGridViewRow = CType(y, DataGridViewRow) ' 提取并统一处理c_seq列的值 Dim valor1 As Integer = GetSeqValue(linha1.Cells("c_seq")) Dim valor2 As Integer = GetSeqValue(linha2.Cells("c_seq")) Dim comparacao As Integer = 0 ' 分场景处理排序逻辑 Select Case True ' 两个都是正数:按升序比较 Case valor1 > 0 AndAlso valor2 > 0 comparacao = valor1.CompareTo(valor2) ' 行1是正数,行2是无效值:行1排前面 Case valor1 > 0 AndAlso valor2 <= 0 comparacao = -1 ' 行1是无效值,行2是正数:行1排后面 Case valor1 <= 0 AndAlso valor2 > 0 comparacao = 1 ' 两个都是无效值:按数值升序排列(也可返回0保持原顺序) Case Else comparacao = valor1.CompareTo(valor2) End Select ' 应用排序方向修饰符 Return comparacao * modificador_ordem End Function ' 提取c_seq值的辅助方法,简化重复逻辑 Private Function GetSeqValue(cell As DataGridViewCell) As Integer If cell.Value Is Nothing OrElse IsDBNull(cell.Value) OrElse Not IsNumeric(cell.Value) Then Return 0 Else Return CInt(cell.Value) End If End Function End Class
关键修正说明
- 将
modificador_ordem改为实例变量,确保每个比较器实例的排序方向独立,不会互相干扰 - 新增
GetSeqValue辅助方法,统一处理null、DBNull、非数值的情况,避免重复代码 - 覆盖所有可能的数值组合场景,严格遵循排序规则:正数升序在前,无效值全部在后
- 使用
CompareTo方法替代手动判断,代码更简洁规范
内容的提问来源于stack exchange,提问作者douglas_forsell
相关产品推荐
相关产品推荐

