实现类似Excel的筛选

news2025/1/16 12:27:20

以下是在 DataGridView 中实现类似 Excel 下拉筛选功能的解决方案:

解决思路

  1. DataGridView 的列添加 DataGridViewComboBoxColumn 类型的列,用于显示下拉筛选列表。
  2. DataGridViewColumnHeaderMouseClick 事件添加处理程序,当用户点击列头时,显示下拉筛选菜单。
  3. 根据列的数据生成下拉列表的选项。

实现代码

using System;
using System.Collections.Generic;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        // 假设你已经将 DataGridView 绑定到数据源,例如通过 FillDataGridView 方法
        FillDataGridView();
    }

    private void FillDataGridView()
    {
        // 假设你有一个数据源,这里使用一个简单的 List 作为示例
        List<TempTaskInfoTable> list = new List<TempTaskInfoTable>();
        // 添加一些数据到列表中
        list.Add(new TempTaskInfoTable { sampleName = "Sample 1", priority = "High" });
        list.Add(new TempTaskInfoTable { sampleName = "Sample 2", priority = "Medium" });
        list.Add(new TempTaskInfoTable { sampleName = "Sample 3", priority = "Low" });

        BindingSource dataSource = new BindingSource();
        dataSource.DataSource = list;
        dataGridView1.DataSource = dataSource;
    }

    private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        DataGridViewColumn column = dataGridView1.Columns[e.ColumnIndex];
        if (column is DataGridViewComboBoxColumn)
        {
            return;
        }
        // 生成下拉列表的选项
        List<string> options = new List<string>();
        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.Cells[e.ColumnIndex].Value!= null)
            {
                string value = row.Cells[e.ColumnIndex].Value.ToString();
                if (!options.Contains(value))
                {
                    options.Add(value);
                }
            }
        }

        DataGridViewComboBoxColumn comboBoxColumn = new DataGridViewComboBoxColumn();
        comboBoxColumn.DataSource = options;
        comboBoxColumn.HeaderText = column.HeaderText;
        comboBoxColumn.Name = column.Name;
        comboBoxColumn.DataPropertyName = column.DataPropertyName;

        // 替换原来的列
        int columnIndex = e.ColumnIndex;
        dataGridView1.Columns.RemoveAt(columnIndex);
        dataGridView1.Columns.Insert(columnIndex, comboBoxColumn);
    }
}


public class TempTaskInfoTable
{
    public string sampleName { get; set; }
    public string priority { get; set; }
}

代码解释

  1. 初始化和数据绑定部分
    • FillDataGridView 方法中,创建一个 List<TempTaskInfoTable> 作为数据源,并添加一些数据。
    • 使用 BindingSource 将数据绑定到 dataGridView1
  2. 列头点击事件处理部分
    • dataGridView1_ColumnHeaderMouseClick 事件处理程序中:
      • 获取用户点击的列。
      • 遍历 dataGridView1 的行,收集该列的所有唯一值,存储在 options 列表中。
      • 创建一个 DataGridViewComboBoxColumn,将 options 作为其数据源。
      • 设置 DataGridViewComboBoxColumnHeaderTextNameDataPropertyName 与原列相同。
      • 移除原列,并将 DataGridViewComboBoxColumn 插入到原列的位置。

使用说明

  1. 在你的 Windows 窗体应用程序中,将上述代码添加到相应的 Form 类中。
  2. 确保你已经在窗体中添加了 dataGridView1 控件。
  3. dataGridView1ColumnHeaderMouseClick 事件关联 dataGridView1_ColumnHeaderMouseClick 方法。
  4. 当用户点击 DataGridView 的列头时,该列将被替换为一个下拉列表,下拉列表的选项是该列的唯一值。

优化建议

  1. 保存原始列的信息,当用户取消筛选时,可以将列恢复为原始状态。
  2. 对于大量数据,可以使用 HashSet<string> 来存储唯一值,提高性能。
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    DataGridViewColumn column = dataGridView1.Columns[e.ColumnIndex];
    if (column is DataGridViewComboBoxColumn)
    {
        return;
    }
    // 生成下拉列表的选项
    HashSet<string> options = new HashSet<string>();
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (row.Cells[e.ColumnIndex].Value!= null)
        {
            string value = row.Cells[e.ColumnIndex].Value.ToString();
            options.Add(value);
        }
    }

    DataGridViewComboBoxColumn comboBoxColumn = new DataGridViewComboBoxColumn();
    comboBoxColumn.DataSource = new List<string>(options);
    comboBoxColumn.HeaderText = column.HeaderText;
    comboBoxColumn.Name = column.Name;
    comboBoxColumn.DataPropertyName = column.DataPropertyName;

    // 替换原来的列
    int columnIndex = e.ColumnIndex;
    dataGridView1.Columns.RemoveAt(columnIndex);
    dataGridView1.Columns.Insert(columnIndex, comboBoxColumn);
}
  1. 可以添加一个按钮或菜单项,用于清除筛选条件,将 DataGridViewComboBoxColumn 恢复为原列。
  2. 对于筛选逻辑,可以添加筛选功能,根据用户选择的下拉选项过滤数据,可使用 DataViewRowFilter 实现。
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    DataGridViewColumn column = dataGridView1.Columns[e.ColumnIndex];
    if (column is DataGridViewComboBoxColumn)
    {
        return;
    }
    HashSet<string> options = new HashSet<string>();
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (row.Cells[e.ColumnIndex].Value!= null)
        {
            string value = row.Cells[e.ColumnIndex].Value.ToString();
            options.Add(value);
        }
    }

    DataGridViewComboBoxColumn comboBoxColumn = new DataGridViewComboBoxColumn();
    comboBoxColumn.DataSource = new List<string>(options);
    comboBoxColumn.HeaderText = column.HeaderText;
    comboBoxColumn.Name = column.Name;
    comboBoxColumn.DataPropertyName = column.DataPropertyName;
    comboBoxColumn.ValueMember = column.DataPropertyName;
    comboBoxColumn.DisplayMember = column.DataPropertyName;
    comboBoxColumn.SelectedIndexChanged += ComboBoxColumn_SelectedIndexChanged;

    // 替换原来的列
    int columnIndex = e.ColumnIndex;
    dataGridView1.Columns.RemoveAt(columnIndex);
    dataGridView1.Columns.Insert(columnIndex, comboBoxColumn);
}

private void ComboBoxColumn_SelectedIndexChanged(object sender, EventArgs e)
{
    DataGridViewComboBoxColumn comboBoxColumn = (DataGridViewComboBoxColumn)sender;
    string selectedValue = comboBoxColumn.SelectedValue.ToString();
    DataView dataView = (DataView)bindingSource.DataSource;
    if (string.IsNullOrEmpty(selectedValue))
    {
        dataView.RowFilter = "";
    }
    else
    {
        dataView.RowFilter = $"{comboBoxColumn.DataPropertyName} = '{selectedValue}'";
    }
}

在上述代码中,为 DataGridViewComboBoxColumnSelectedIndexChanged 事件添加了处理程序,根据用户的选择更新 RowFilter 以实现筛选功能。

注意事项

  1. 当处理用户选择时,需要确保数据类型匹配,避免类型转换异常。
  2. 对于复杂的数据类型,可能需要自定义 ToString 方法或使用其他数据转换方式。
  3. 当处理大量数据时,需要考虑性能问题,例如在生成下拉列表选项时,可以使用异步操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

链家房价数据爬虫和机器学习数据可视化预测

完整源码项目包获取→点击文章末尾名片&#xff01;

亿道三防丨三防笔记本是什么意思?和普通笔记本的优势在哪里?

三防笔记本是什么意思&#xff1f;和普通笔记本的优势在哪里&#xff1f; 在现代社会中&#xff0c;笔记本电脑已经成为人们工作和生活中不可或缺的一部分。然而&#xff0c;在一些特殊行业或环境中&#xff0c;普通笔记本电脑由于其脆弱性和对环境条件的敏感性&#xff0c;往…

通过proto文件构建 完整的 gRPC 服务端和客户端案例

基础教程-简单案例&#xff08;快入入门java-grpc框架&#xff09; 参考官方入门案例教程&#xff1a;里面我看proto编译&#xff0c;其实直接用maven就能直接将.proto文件编译成java代码。快速入门 | Java | gRPC 框架https://grpc.org.cn/docs/languages/java/quickstart/ …

UML系列之Rational Rose笔记九:组件图

一、新建组件图 二、组件图成品展示 三、工作台介绍 最主要的还是这个component组件&#xff1b; 然后还有这几个&#xff0c;正常是用不到的&#xff1b;基本的使用第四部分介绍一下&#xff1a; 四、基本使用示例 这些&#xff0c;主要是运用package还有package specifica…

K8S 节点选择器

今天我们来实验 pod 调度的 nodeName 与 nodeSelector。官网描述如下&#xff1a; 假设有如下三个节点的 K8S 集群&#xff1a; k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、镜像准备 1.1、镜像拉取 docker pull tomcat:8.5-jre8…

c++领域展开第十二幕——类和对象(STL简介——简单了解STL)超详细!!!!

文章目录 前言STL简介什么是STLSTL的版本STL的六大组件STL的重要性如何学习STL 总结 前言 上篇博客我们了解了初阶的模版函数&#xff0c;以及有关的一些使用方法。 今天我们来了解了解STL库的有关知识 跟我一起上车吧 STL简介 什么是STL STL&#xff1a;是C标准库的重要组成…

Onedrive精神分裂怎么办(有变更却不同步)

Onedrive有时候会分裂&#xff0c;你在本地删除文件&#xff0c;并没有同步到云端&#xff0c;但是本地却显示同步成功。 比如删掉了一个目录&#xff0c;在本地看已经删掉&#xff0c;onedrive显示已同步&#xff0c;但是别的电脑并不会同步到这个删除操作&#xff0c;在网页版…

科研绘图系列:R语言绘制微生物物种系统发育树(phylogenetic tree)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍构成要素有根树与无根树构建方法应用领域说明的问题教程加载R包数据下载导入数据数据预处理系统发育树可视化准备画图数据1. 构建基础系统发育树 `p1`2. 添加条形图 `p2`3. 添加热图…

1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)

目录 01. Java中的集合体系 02. 单列集合体系​ 1. Collection系列集合的遍历方式 &#xff08;1&#xff09;迭代器遍历&#xff08;2&#xff09;增强for遍历​编辑&#xff08;3&#xff09;Lambda表达式遍历 03.List集合详解 04.Set集合详解 05.总结 Collection系列…

微信小程序:跨页面数据修改全攻略

一、引言 在微信小程序开发中&#xff0c;常常会遇到需要在不同页面之间修改数据的情况。比如在商品详情页添加商品到购物车后&#xff0c;购物车页面需要实时更新商品数量和总价&#xff1b;在用户设置页面修改了个人信息&#xff0c;首页的用户信息展示区域也需要同步更新。…

寒假第一次牛客周赛 Round 76回顾

AC数&#xff1a;2&#xff08;A、C&#xff09; B 思路&#xff1a; 等价于求&#xff1a; 数量最多的字符 #include<stdio.h> int main() {int n,num;int a[26]{0};//用于存储字母 a 到 z 的出现次数。scanf("%d",&n);char s[n];scanf("%s",s)…

【 PID 算法 】PID 算法基础

一、简介 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&#xff09;、Differential&#xff08;微分&#xff09;的缩写。也就是说&#xff0c;PID算法是结合这三种环节在一起的。粘一下百度百科中的东西吧。 顾名思义&#xff0c;…

Ubuntu打开文件夹不显示文件

1.情况介绍 使用ubuntu打开文件夹不显示文件夹里面的内容&#xff0c;而是直接打开了资源查看器。 2.解决办法 命令行安装nautilus sudo apt-get install nautilus

java.text.SimpleDateFormat (日期)

前言&#xff1a; 小编最近让流感折磨的快嘎啦&#xff0c; 呜呜呜&#xff0c;拖更了俩天&#xff0c; 从明天开始我们继续日更&#xff01;&#xff01;&#xff01;&#xff01; 我们一直都是以这样的形式&#xff0c;让新手小白轻松理解复杂晦涩的概念&#xff0c; 把Ja…

游戏市场成果及趋势

2024 年的游戏行业发展情况如何&#xff1f;这是一个既关系到开发商&#xff0c;又关系到玩家的问题&#xff0c;而市场分析师可以为我们揭晓答案。下面&#xff0c;就让我们来看看分析师给出的结论以及他们对未来趋势的预测。 玩家 自 2021 年起&#xff0c;全球平均游戏时间…

Java版-oracle数据库连接测试工具-Maven配置JDBC

一、目标: 1)数据迁移方案,原RAC,新RAC 2)关闭原RAC环境,修改新RAC环境的IP=原RAC环境的IP,优点:所有的应用端不用修改数据库连接字符串。 3)测试工具目标: 3.1 Java程序,运行后cmd窗口, 3.2 链接原RAC数据库IP,每2秒查询并显示数据; 3.3 关闭/断掉原RAC服务器,…

微信小程序实现个人中心页面

文章目录 1. 官方文档教程2. 编写静态页面3. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/ 2. 编写静态页面 mine.wxml布局文件 <!--index.wxml--> <navigation-bar title"个人中心" ba…

数据结构-ArrayLIst-一起探索顺序表的底层实现

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 大家好&#xff0c;我们今天来学习java数据结构的第一章ArrayList&#xff08;顺序表&#xff09; 1.ArrayList的概念 那小伙伴就要问了线性表到…

Unity2017 控制.abc格式的三维动画播放

首先需要导入插件Alembic&#xff0c;否则导入abc动画&#xff0c;Unity是不会识别的。 Unity2017版本及以下直接从我这儿下载&#xff1a;https://download.csdn.net/download/qq_41603955/90272382 高版本Unity&#xff0c;请移步AssetStore商店搜找。 导入abc之后&#x…

docker虚拟机平台未启用问题

在终端中输入如下代码&#xff0c;重启电脑即可 Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform 对于Docker Desktop - Unexpected WSL error问题 参考链接 解决WSL2与docker冲突问题