实现类似Excel的筛选

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

解决思路

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

实现代码

csharp 复制代码
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> 来存储唯一值,提高性能。
csharp 复制代码
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 实现。
csharp 复制代码
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. 当处理大量数据时,需要考虑性能问题,例如在生成下拉列表选项时,可以使用异步操作。
相关推荐
番石榴AI1 小时前
自己动手做一款ChatExcel数据分析系统,智能分析 Excel 数据
人工智能·python·数据挖掘·excel
Lucky GGBond5 小时前
使用 EasyExcel 封装通用 Excel 导出工具类
excel
似水流年 光阴已逝10 小时前
从Excel姓名匹配案例学Python:由点及面的系统化学习指南
开发语言·python·excel
best_scenery11 小时前
用excel绘制茎叶图
excel·分布图
rannn_1111 天前
【学以致用|python自动化办公】OCR批量识别自动存为Excel(批量识别发票)
python·ocr·excel·财务
小钱c71 天前
Python使用 pandas操作Excel文件并新增列数据
python·excel·pandas
Shi_haoliu1 天前
Vue2 + Office Add-in关于用vue项目于加载项控制excel单元格内容(Demo版)
前端·javascript·vue.js·node.js·html·excel·office
njsgcs1 天前
json转excel python pd
python·json·excel·pd
RECRUITGUY2 天前
Excel中将毫秒时间戳转换为标准时间格式
excel
SunkingYang2 天前
详细介绍C++中捕获异常类型的方式有哪些,分别用于哪些情形,哪些异常捕获可用于通过OLE操作excel异常
c++·excel·mfc·异常捕获·comerror