自定义比较器 datagridview 排序

2023-12-10

我有一个 datagridview,其中绑定源作为数据源,绑定源有一个数据表作为数据源。有些列是字符串,但我希望它们以特定方式排序。

网格将它们排序为 1, 10, 10,0 44a, 6c。

但我希望对它们进行排序:1、6c、10、44a、100,就好像我只从值中取出数字并相应地对它们进行排序。

有没有办法在对某些列进行排序时添加自定义比较器?如果网格、绑定源、数据表架构未更改,任何其他解决方案都可以。


Is there a way I can add a custom comparer Yes!

当 DGV 绑定到DataSource,您必须对源采取行动(排序),而不是 DGV 本身。这排除了一些选项,例如使用SortCompare事件。下面的方法使用DataView.

首先,我从来自这个答案的自然字符串排序器并做了一些更改:

Imports System.Runtime.InteropServices

Partial Class NativeMethods
    <DllImport("shlwapi.dll", CharSet:=CharSet.Unicode)>
    Private Shared Function StrCmpLogicalW(s1 As String, s2 As String) As Int32
    End Function

    Friend Shared Function NaturalStringCompare(str1 As String, str2 As String) As Int32
        Return StrCmpLogicalW(str1, str2)
    End Function
End Class

Public Class NaturalStringComparer
    Implements IComparer(Of String)
    Private mySortFlipper As Int32 = 1

    Public Sub New()

    End Sub

    Public Sub New(sort As SortOrder)
        mySortFlipper = If(sort = SortOrder.Ascending, 1, -1)
    End Sub

   Public Function Compare(x As String, y As String) As Integer _
            Implements IComparer(Of String).Compare

        ' convert DBNull to empty string
        Dim x1 = If(String.IsNullOrEmpty(x), String.Empty, x)
        Dim y1 = If(String.IsNullOrEmpty(y), String.Empty, y)

        Return (mySortFlipper * NativeMethods.NaturalStringCompare(x1, y1))
    End Function
End Class

正如链接问题所证明的那样,该比较器可以以多种方式使用。它通常用于诸如List文件名。由于这里的排序目标是数据库数据,因此添加了几行Compare当遇到空数据时。 (OP,mvaculisteanu,发现传递空值时速度很慢)。

这也可以工作,作为单独的步骤处理,可以轻松添加其他边缘情况:

Return (mySortFlipper * NativeMethods.NaturalStringCompare(If(x, ""), If(y,""))

我不知道你是如何使用的BindingSource,所以我不得不对配置进行一些猜测。我的测试DataTable有 3 列,#1 设置为编程以实现比较器。使用的表单级别对象变量(这样您就了解我的配置 - 希望它是相似的):

Private dgvDV As DataView
Private dgvBS As BindingSource

' config:
dgvDV = New DataView(dgvDT)

dgvBS = New BindingSource()
dgvBS.DataMember = "myDT"
dgvBS.DataSource = dgvDT

dgv2.Columns(0).SortMode = DataGridViewColumnSortMode.Automatic
dgv2.Columns(1).SortMode = DataGridViewColumnSortMode.Programmatic
dgv2.Columns(2).SortMode = DataGridViewColumnSortMode.Automatic

魔法就发生在ColumnHeaderMouseClick event:

Private SortO As SortOrder = SortOrder.Ascending
Private Sub dgv2_ColumnHeaderMouseClick(sender As Object...etc

    ' the special column we want to sort:
    If e.ColumnIndex = 1 Then
        ' create new DV
        dgvDV = DGVNaturalColumnSort("Text", SortO)

        ' reset the BindingSource:
        dgvBS.DataSource = dgvDV
        ' update glyph
        dgv2.Columns(1).HeaderCell.SortGlyphDirection = SortO

        ' flip order for next time:
        SortO = If(SortO = SortOrder.Ascending, SortOrder.Descending, SortOrder.Ascending)
    End If
End Sub

然后,一个辅助函数实现排序并创建一个新的DataView:

Private Function DGVNaturalColumnSort(colName As String, sortt As SortOrder) As DataView
    Dim NComparer As New NaturalStringComparer(sortt)
    Dim tempDT = dgvDV.Table.AsEnumerable().
        OrderBy(Function(s) s.Field(Of String)(colName), NComparer).
        CopyToDataTable

    Return New DataView(tempDT)
End Function

因为您传递了列的名称,所以当有多个此类列时应该很容易使用。结果:

enter image description here

将 None 排序在顶部,然后将 Asc 和 Desc 排序在下面

用户对列的更改(例如顺序和宽度)将被保留。这也是工作得很好,没有 a BindingSource。只需使用你的DataView as the DataSource:

  dgvBS.DataSource = dgvDV

Using a DataTable as the DataSource可能会出现问题并且“更重”,因为您必须复制表格。 ADataView让这变得非常简单。


我也发现了这个java 的字母数字排序器。出于好奇,我将其转换为.NET 进行比较。它运作良好,但不完全相同。给定相同的起点,1000 个序列中的 25-35 个通常会出现不同的结果:

 PInvoke:  03, 03, 03s, 3A
Alphanum:  03, 3A...3RB, 03s, 3X 

这并不完全错误,03s位于正确的区域,之后结果会同步备份一段时间。它还以不同的方式处理前导破折号,并且比 PInvoke 慢一些。但它确实可以很好地处理 Nothing 值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义比较器 datagridview 排序 的相关文章

  • 插入多重集中:在该值第一次出现之前而不是最后一次出现之后

    正如标题所示 multiset 在所有相同值的范围末尾插入一个值 例如 在多重集中插入 21 2 2 3做到了1 2 2 new 2 3 如何在所有相同值的范围开头插入新值 例如 在多重集中插入 21 2 2 3应该使1 new 2 2 2
  • OpenSSL:RSA 加密/解密、密钥生成和密钥持久性

    我正在尝试构建一个需要以下内容的 p2p 应用程序 在 OpenSSL 中使用 RSA Encryption Decryption Generating Keys done Saving and loading keys done Savi
  • 为什么纯虚拟析构函数的实现必须为空?它应该是内联的吗?

    我在其他线程中读到 当您实现纯虚拟析构函数 是的 它可以有一个实现 时 它必须是空的 并且应该 是内联的 应该是空的吗 如果是这样 为什么 应该内联吗 如果是这样 为什么 编辑 这就是纯虚拟析构函数的实现方式 class A virtual
  • MVC 2视图显示错误的模型信息

    我在一个项目中使用 MVC 2 但我遇到了视图问题 在控制器中我有代码 return View calendarDay 如果我调试这一行并检查 calendarDay 它会告诉我 calendarDay Id 属性等于 2 在视图中我有一些
  • 资源文件中的控制字符 C#

    我想添加Left To Right控制字符在resource resx文件输入Visual Studio 我在互联网上搜索并找到了一个名为在 NET 资源文件中转义序列的另一种方法 http www devx com tips Tip 34
  • 如何防止函数中的隐式转换?

    我正在编写一个实用程序类 其中包含 IsEquals 和 IsGreaterThanEquals 等接受 double 类型参数的方法 当我将浮点值发送到方法时 它们会隐式转换为双精度值并进行比较 我不希望这种事发生 当我发送 float
  • Linq Any 始终返回 true

    我已经使用 Linq to Entities 多年 但这是我第一次遇到这个问题 我有Tips and Items表 每个提示可以有很多项目 我的数据库中只有 3 个项目 编辑项目时 我想确保GivenId对于具有相同提示的项目 字段是唯一的
  • 具有 Nhibernate 设计问题的领域模型

    我正在尝试进入 DDD with C 世界 我使用NHibernate作为我的ORM工具 因此尝试开发一个PI Persistence Ignorance 模型 但是 在我的一些实体 表示为 POCOS 中 我的属性设置器中有业务规则 例如
  • 除非我在开​​始时声明变量,否则为什么会收到“错误未声明的标识符”?

    当我有以下情况时 include stdafx h include
  • ofstream::operator<<(streambuf) 是一种复制文件的缓慢方法

    我需要一种跨平台 无需外部库的复制文件的方式 在我的第一遍中 我想出了 省略错误处理 char buffer LEN ifstream src srcFile ios in ios binary ofstream dest destFile
  • 使用 MemoryCache 而不是普通的旧 Dictionary 的令人信服的理由是什么

    我刚刚遇到内存缓存 http msdn microsoft com en us library system runtime caching memorycache aspx这是 NET 4 中的新增功能 我知道如果你想的话它会很有用 限制
  • llvm clang 编译器上的dynamic_cast失败

    我看到一个奇怪的失败dynamic cast正在返回NULL在 clang 编译器上 但相同的代码可以在 gcc 环境下运行 您能否指出根本原因是什么 之间可能有什么区别dynamic cast关于 llvm 和 gcc 我正在使用两个编译
  • WiX 安装程序在 vs 2012 上不起作用

    我想为我的应用程序创建一个安装程序 我已经下载了 WiX 3 6 并将其安装在 vs 2012 上 创建简单的winform应用程序 将 WiX 安装项目添加到我的解决方案中 右键单击参考并将我的 winform 应用程序添加到安装程序的参
  • 成员函数的Decltype

    class A int f int x int j return 2 decltype f p 给我错误 error decltype cannot resolve address of overloaded function 我不明白为什
  • 在方法签名中使用 new 关键字通常只是为了可读性吗?

    我读过关于new关键词在方法签名中并看到了下面的例子this https stackoverflow com questions 1014295 c sharp new keyword in method signature发帖了 但还是不
  • 实现多个接口的 Service Fabric Actor 接口

    我正在构建一个应用程序 其中有多个不同的参与者类型 这些参与者类型对于某些不同的数据对象具有相同类型的行为 CRUD 为了更轻松地创建处理此问题的代码 我尝试创建一个这些参与者可以实现的接口 这意味着我有一个看起来像这样的参与者界面 pub
  • TPL架构问题

    我目前正在开展一个项目 我们面临并行处理项目的挑战 到目前为止没什么大不了的 现在来说说问题 我们有一个 ID 列表 我们定期 每 2 秒 为每个 ID 调用一个 StoredProcedure 需要单独检查每个项目的 2 秒 因为它们是在
  • Windows 安装程序 (C#) 错误代码 2869

    我在 VS 2005 中有一个项目 其中有一个控制台应用程序和一个与安装该应用程序关联的安装项目 我在控制台应用程序中还有一个安装程序类 安装项目将使用它在安装前进行一些验证 这些任务正在检查数据库连接字符串并检查某些目录位置以确保它们在安
  • Interlocked.CompareExchange 可以抛出 NullReferenceException 吗?

    From https msdn microsoft com en us library bb297966 v vs 110 aspx https msdn microsoft com en us library bb297966 v vs
  • 如何用纯色填充位图?

    我需要使用唯一的 RGB 颜色创建 24 位位图 分辨率 100x100 像素 并将生成的图像保存到磁盘 我目前使用的是SetPixel http msdn microsoft com en us library 6c7eyzyb aspx

随机推荐