自学内容网 自学内容网

实现类似Excel的筛选

以下是在 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. 当处理大量数据时,需要考虑性能问题,例如在生成下拉列表选项时,可以使用异步操作。

原文地址:https://blog.csdn.net/qq_25699299/article/details/145167419

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!