找回密码
 注册 (不支持IE浏览器)
搜索
查看: 12|回复: 0

[WinForm] 扩展DevExpress GridControl实现隐藏列筛选功能

[复制链接]

0

精华

235

贡献

140

赞扬

回帖
9
软币
1595
在线时间
78 小时
注册时间
2016-9-8
发表于 昨天 16:42 | 显示全部楼层 |阅读模式
本帖最后由 cosky 于 2026-3-1 18:01 编辑
名词解释:
1、文中提到的GridControl均为DevExpress中的GridControl控件。
2、GridView为DevExpress中GridControl控件中的GridView视图。

一、前言:
在企业级应用开发中,数据表格(Grid)是最重要的UI组件之一。DevExpress的GridControl作为业界领先的网格控件,提供了丰富的功能和高度的可定制性。
其中我们经常需要对表格数据进行查询筛选操作。GridView提供了方便的接口函数,调用GridView.ApplyFindFilter(string filterText)方法即可快速对视图中的数据进行查找和筛选。
但是,GridControl中的筛选功能只能针对视图中已显示的列(GridColumn.Visible = true)进行筛选,隐藏列的无法进行查找和筛选。
这种设计在某些业务场景下显得不够灵活。
我们设想一下:有一个产品列表数据,包括:编号、产品名称、描述等字段。现在我们为了方便用户搜索增加了一个快速搜索字段,内容是由产品名称或者描述转换成拼音以及拼音首字母。这样用户敲几个拼音字母就可以方便的进行查找和筛选了。很显然这个和业务无关的快速搜索字段我们不希望它在视图中显示,但是GridControl中的设定又是隐藏的列无法被筛选(一根筋两头堵了属于是)
如图:
GridControlFindFilter.gif

针对这个问题有人提交过issue,官方的回复是:“筛选隐藏的列?这很奇怪,也会让用户感到困扰!”。
emmm...看样子官方是不打算改进了。
别急,本文将详细介绍如何通过继承和扩展DevExpress的GridControl来实现这一高级功能,包括其背后的设计模式、架构原理以及具体的实现细节。

二、DevExpress GridControl 核心架构
在扩展前,先理解 GridControl 的插件式架构(基于策略模式 + 工厂模式),这是自定义扩展的基础:
DevExpress的GridControl采用了一套复杂的插件式架构:
GridControl
├── View (BaseView)
│   ├── ViewInfo (BaseViewInfo)
│   ├── Handler (BaseViewHandler)
│   └── Painter (BaseViewPainter)
└── InfoRegistrator (GridInfoRegistrator)

这种设计模式基于策略模式和工厂模式,每个组件各司其职:
  • GridControl: 控件容器,管理视图生命周期
  • View: 数据展示逻辑的核心,
  • ViewInfo: 视图状态和布局信息
  • Handler: 用户交互处理
  • Painter: 视觉渲染
  • InfoRegistrator: 视图类型的注册和创建

三、分步实现:自定义 GridControl 支持隐藏列筛选

1. 核心:CustomGridView(重写筛选列集合逻辑)
这是实现隐藏列筛选的核心类,关键是重写GetFindToColumnsCollection方法 —— 该方法决定了哪些列参与筛选。
[C#] 纯文本查看 复制代码
using DevExpress.XtraGrid.Views.Grid;
using System.Collections.Generic;

public class CustomGridView : GridView
{
    // 无参构造函数
    public CustomGridView() { }
    
    // 带GridControl的构造函数(关联控件容器)
    public CustomGridView(GridControl grid) : base(grid) { }

    /// <summary>
    /// 重写筛选列集合逻辑:添加隐藏列到筛选集合
    /// </summary>
    /// <returns>包含可见列+符合条件的隐藏列的筛选集合</returns>
    protected override List<IDataColumnInfo> GetFindToColumnsCollection()
    {
        // 1. 先获取默认的可见列筛选集合
        List<IDataColumnInfo> filterColumns = base.GetFindToColumnsCollection();
        
        // 2. 遍历所有列,将「隐藏且未分组」的列加入筛选集合
        foreach (GridColumn column in Columns)
        {
            // 条件说明:
            // !column.Visible → 仅处理隐藏列
            // column.GroupIndex == -1 → 排除分组列(避免重复处理)
            if (!column.Visible && column.GroupIndex == -1)
            {
                // 为隐藏列创建筛选所需的列信息对象
                filterColumns.Add(CreateIDataColumnInfoForFilter(column));
            }
        }
        
        return filterColumns;
    }

    // 标识自定义视图名称(需与注册器一致)
    protected override string ViewName => "CustomGridView";
}


核心逻辑解析:
  • base.GetFindToColumnsCollection():先保留原有可见列的筛选逻辑,保证默认功能不受影响;
  • 遍历所有列,筛选出「隐藏且未分组」的列,通过CreateIDataColumnInfoForFilter方法为其创建筛选所需的IDataColumnInfo对象,加入筛选集合;
  • 排除分组列(GroupIndex == -1)是关键的性能优化,避免重复处理。

2. 视图注册器:CustomGridViewInfoRegistrator
这是 DevExpress 插件架构的「工厂类」,负责注册自定义视图,并创建配套的 ViewInfo/Handler/Painter 组件(即使暂时不需要自定义这些组件,也需适配创建,保证架构完整性)。
[C#] 纯文本查看 复制代码
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;

public class CustomGridViewInfoRegistrator : GridInfoRegistrator
{
    // 自定义视图名称(需与CustomGridView的ViewName一致)
    public override string ViewName => "CustomGridView";

    // 创建自定义视图实例
    public override BaseView CreateView(GridControl grid)
    {
        return new CustomGridView(grid);
    }

    // 创建视图信息对象(适配默认实现)
    public override BaseViewInfo CreateViewInfo(BaseView view)
    {
        return new CustomGridViewInfo(view as CustomGridView);
    }

    // 创建交互处理对象(适配默认实现)
    public override BaseViewHandler CreateHandler(BaseView view)
    {
        return new CustomGridViewHandler(view as CustomGridView);
    }

    // 创建渲染对象(适配默认实现)
    public override BaseViewPainter CreatePainter(BaseView view)
    {
        return new CustomGridViewPainter(view as CustomGridView);
    }
}


3. 自定义控件容器:CustomGridControl
将自定义视图注册到 GridControl,使其成为默认视图,同时支持 Visual Studio 工具箱拖拽使用(控件拖拽用户狂喜)。
[C#] 纯文本查看 复制代码
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Registrator;
using System.ComponentModel;

[ToolboxItem(true)] // 使控件在VS工具箱中可见
public class CustomGridControl : GridControl
{
    /// <summary>
    /// 重写默认视图创建逻辑:使用自定义的CustomGridView
    /// </summary>
    protected override BaseView CreateDefaultView()
    {
        return CreateView("CustomGridView");
    }

    /// <summary>
    /// 注册自定义视图类型到控件
    /// </summary>
    protected override void RegisterAvailableViewsCore(InfoCollection collection)
    {
        // 先注册默认视图,保证原有功能
        base.RegisterAvailableViewsCore(collection);
        // 添加自定义视图注册器
        collection.Add(new CustomGridViewInfoRegistrator());
    }
}


4. 辅助组件:适配默认实现
以下三个类为适配架构的辅助类,无需修改核心逻辑,仅需继承对应基类即可:
[C#] 纯文本查看 复制代码
// CustomGridViewInfo:视图信息类
using DevExpress.XtraGrid.Views.Grid.ViewInfo;

public class CustomGridViewInfo : GridViewInfo
{
    public CustomGridViewInfo(CustomGridView view) : base(view) { }
}

// CustomGridViewHandler:交互处理类
using DevExpress.XtraGrid.Views.Grid.Handler;

public class CustomGridViewHandler : GridHandler
{
    public CustomGridViewHandler(CustomGridView view) : base(view) { }
}

// CustomGridViewPainter:渲染类
using DevExpress.XtraGrid.Views.Grid.Painters;

public class CustomGridViewPainter : GridPainter
{
    public CustomGridViewPainter(CustomGridView view) : base(view) { }
}


四、使用方式
  • 编译上述代码生成控件库,在 VS 工具箱中找到CustomGridControl,拖拽到窗体;
  • 像使用普通 GridControl 一样绑定数据,添加需要隐藏的「拼音检索列」并设置Visible = false;
  • 调用CustomGridView.ApplyFindFilter("拼音关键词"),即可实现基于隐藏列的筛选。

五、性能与扩展建议
  • 性能优化:若表格数据量极大(10 万 + 行),可在GetFindToColumnsCollection中增加列白名单,仅将需要筛选的隐藏列加入集合,避免遍历所有列;
  • 扩展方向:可新增属性(如AllowHiddenColumnFilter),控制是否启用隐藏列筛选,提升控件灵活性;
  • 兼容性:该实现基于 DevExpress 通用架构,适配 v18.2 + 版本(低版本需微调命名空间)。

总结
  • 实现隐藏列筛选的核心是重写GridView.GetFindToColumnsCollection方法,将符合条件的隐藏列加入筛选集合;
  • DevExpress GridControl 的插件式架构(策略 + 工厂模式)是扩展的基础,需通过 InfoRegistrator 注册自定义视图及配套组件;
  • 扩展过程中需保留原有逻辑(调用 base 方法),仅增量修改核心逻辑,保证控件原有功能不受影响。

通过这种方式,我们既解决了业务痛点,又遵循了 DevExpress 的架构设计,实现了高可维护性的自定义扩展。最终看看效果吧

CustomGridControlFindFilter.gif
【完美】

完整方案下载:
Snipaste_2026-03-01_16-54-41.png

Demo项目环境:
IDE:Visual Studio 2022
框架:.Net Framework 4.8 (代码兼容.net 10)
DevExpress:24.2.6 (下载后可自行升级到更高版本)

GridControlAllowFilteringHiddenColumns.rar

19.05 KB, 下载次数: 0

售价: 2 源码  [记录]  [购买附件]  [充值源码]

回复

使用道具 举报

本版积分规则

Archiver|手机版|小黑屋|开发者网 ( 苏ICP备08004430号-2 )
版权所有:南京韵文科技有限公司 苏公网安备32011302322501号

GMT+8, 2026-3-2 06:29

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表