实现类似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. 当处理大量数据时,需要考虑性能问题,例如在生成下拉列表选项时,可以使用异步操作。
相关推荐
葡萄城技术团队1 天前
从100秒到10秒的性能优化,你真的掌握 Excel 的使用技巧了吗?
excel
QQ3596773452 天前
ArcGIS Pro实现基于 Excel 表格批量创建标准地理数据库(GDB)——高效数据库建库解决方案
数据库·arcgis·excel
星空的资源小屋4 天前
Digital Clock 4,一款免费的个性化桌面数字时钟
stm32·单片机·嵌入式硬件·电脑·excel
揭老师高效办公4 天前
在Excel和WPS表格中批量删除数据区域的批注
excel·wps表格
我是zxb4 天前
EasyExcel:快速读写Excel的工具类
数据库·oracle·excel
辣香牛肉面4 天前
[Windows] 搜索文本2.6.2(从word、wps、excel、pdf和txt文件中查找文本的工具)
word·excel·wps·搜索文本
ljf88384 天前
Java导出复杂excel,自定义excel导出
java·开发语言·excel
tebukaopu1484 天前
json文件转excel
json·excel
shizidushu4 天前
How to work with merged cells in Excel with `openpyxl` in Python?
python·microsoft·excel·openpyxl
Eiceblue5 天前
使用 C# 设置 Excel 单元格格式
开发语言·后端·c#·.net·excel