You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现即插即用DataGridView工具类:扩展Rows.Clear()保留筛选行

自定义带筛选行的DataGridView:仅扩展Rows.Clear()逻辑的即插即用方案

问题背景

我需要开发一个带筛选行的自定义DataGridView,作为现有程序中所有DataGridView的即插即用替代组件。要求原有常规行操作(如Rows.Add等)完全正常工作,但需要给Rows.Clear()添加额外逻辑——执行Clear后自动恢复筛选行。但Rows.Clear()无法直接重载,我尝试了以下方案:

Public Class dgv_with_filterrow
    Inherits DataGridView
    Private customRows As New CustomDataGridViewRowCollection(Me)

    Public Shadows ReadOnly Property Rows As CustomDataGridViewRowCollection
        Get
            Return customRows
        End Get
    End Property

    Public Overrides Sub Refresh()
        ' Add your custom implementation here
        Console.WriteLine("Custom Refresh() method called")

        ' Call the base class implementation
        MyBase.Refresh()
    End Sub

    ' Add other overridden methods as needed

    Public Class CustomDataGridViewRowCollection
        Inherits DataGridViewRowCollection

        Public Sub New(ByVal dataGridView As DataGridView)
            MyBase.New(dataGridView)
        End Sub

        ' Override the Clear method to provide custom behavior
        Public Overrides Sub Clear()
            ' Your custom implementation goes here
            Console.WriteLine("Custom Rows.Clear() method called")

            ' Call the base class implementation
            MyBase.Clear()
        End Sub
    End Class
End Class

现有方案问题

上述代码的核心问题在于DataGridViewRowCollection的构造函数是**受保护(Protected)**的,无法直接实例化自定义的CustomDataGridViewRowCollection,导致除Clear外的其他行操作(如Rows.Add、Rows.Remove等)无法正常调用基类逻辑,引发功能异常。

解决方案:利用事件拦截+避免重写整个RowCollection

不需要自定义RowCollection,而是通过监听DataGridView的RowsCleared事件,在Clear操作完成后自动恢复筛选行;同时保证所有原生行操作不受影响。

最终实现代码

Public Class dgv_with_filterrow
    Inherits DataGridView

    ' 标记是否是内部触发的筛选行添加,避免循环触发
    Private isReAddingFilterRow As Boolean = False

    Public Sub New()
        MyBase.New()
        ' 初始化时添加筛选行
        AddFilterRow()
        ' 绑定RowsCleared事件,在Clear后恢复筛选行
        AddHandler Me.RowsCleared, AddressOf OnRowsCleared
    End Sub

    ' 处理RowsCleared事件,在Clear完成后恢复筛选行
    Private Sub OnRowsCleared(sender As Object, e As DataGridViewRowsClearedEventArgs)
        If Not isReAddingFilterRow Then
            isReAddingFilterRow = True
            ' 重新添加筛选行
            AddFilterRow()
            isReAddingFilterRow = False
        End If
    End Sub

    ' 封装添加筛选行的逻辑
    Private Sub AddFilterRow()
        ' 创建筛选行(示例:添加一行作为筛选行)
        Dim filterRow As New DataGridViewRow()
        ' 自定义筛选行的样式/内容,比如添加ComboBox、TextBox等控件
        For Each col As DataGridViewColumn In Me.Columns
            Dim cell As DataGridViewCell = col.CellTemplate.Clone()
            cell.Value = "筛选..." ' 示例提示文本
            filterRow.Cells.Add(cell)
        Next
        ' 将筛选行插入到第一行
        Me.Rows.Insert(0, filterRow)
        ' 设置筛选行样式区分
        filterRow.DefaultCellStyle.BackColor = Color.LightGray
    End Sub
End Class

方案优势

  1. 即插即用:直接替换现有程序中的DataGridView为dgv_with_filterrow即可生效,无需修改原有代码中的Rows.Add、Rows.Clear等调用
  2. 原生操作完全兼容:所有原生行操作(Add、Remove、Insert等)保留原有逻辑,无需重写
  3. 精准扩展Clear逻辑:仅在Rows.Clear()执行完成后自动恢复筛选行,其他操作不受干扰
  4. 绕过构造函数限制:无需自定义DataGridViewRowCollection,避免了基类构造函数受保护的问题

关键说明

  • isReAddingFilterRow标记用于避免添加筛选行时再次触发RowsCleared事件,造成循环添加
  • AddFilterRow方法可根据需求自定义筛选行的控件(比如添加下拉框、文本框等筛选组件)
  • 若需要在Clear操作之前执行逻辑(如保存当前筛选条件),可新增Shadow覆盖的ClearRows方法,内部先执行前置逻辑再调用MyBase.Rows.Clear()

内容的提问来源于stack exchange,提问作者Ukkie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 20:03:12