基于两个comboboex过滤DGV

基于两个comboboex过滤DGV

本文介绍了基于两个comboboex过滤DGV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hi,
I have the tblEmp which populates my datagridview. I wanna now filter the records depending on two comboboxes.

            tblEmp
FName	LName	Age	City
Mike	Brown	25	Berlin
James	Blue	35	Accra
Philip	Gay	20	London
Simon	Black	15	Berlin
Martin	Adjei	45	London
Peter	Moore	33	Pari
Philip	Gay	51	Berlin		







The first combobox (cb1) is filed with the city names + the string All &
The second one (cb2) is filled with LNames + the string All.

To filter the dgv based on one combobox is not the problem.
My Problem is how can i ajust my code so that the filtering takes both comboboxes into consideration?? And if I select All it should then show me again all records in the dgv.

That's my code for the filtering (It's also the same for cb2):







private void cb1_SelectedIndexChanged(object sender, EventArgs e)
{
    string showall = cb1.SelectedItem.ToString();
    if (showall == "All")
    {


    }

    else if (cb1.SelectedItem != null)
    {
        //Check an see what's in the dgv
        DataView dv = new DataView(dt);
        // now filter
        dv.RowFilter = " [City] = " + cb1.Text.Trim();
        datgridview1.DataSource = dv;

    }
    else
    {
        MessageBox.Show("No records found");
    }
}







So that's my records if i choose [Berlin] in the cb1 (That' working)

FName	LName	Age	City
Mike	Brown	25	Berlin
Simon	Black	15	Berlin
Philip	Gay	51	Berlin

MY QUESTION: How Can I Get this record when i select [Berlin] in cb1 & [Gay] in cb2?

FName	LName	Age	City
Philip	Gay	51	Berlin

OR [London] & [Adjei]?

FName	LName	Age	City
Martin	Adjei	45	London

OR [All] & [Gay]?



FName	LName	Age	City
Philip	Gay	20	London
Philip	Gay	51	Berlin

推荐答案

private DataTable _dt;

public Form1()
{
    InitializeComponent();
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    LoadData();
    LoadFilterData();

    FilterData();
}

private void LoadData()
{
    // Create table
    _dt = new DataTable();
    _dt.Columns.Add("FName", typeof(string));
    _dt.Columns.Add("LName", typeof(string));
    _dt.Columns.Add("Age", typeof(int));
    _dt.Columns.Add("City", typeof(string));

    // Fill data
    _dt.Rows.Add("Mike", "Brown", 25, "Berlin");
    _dt.Rows.Add("James", "Blue", 35, "Accra");
    _dt.Rows.Add("Philip", "Gay", 20, "London");
    _dt.Rows.Add("Simon", "Black", 15, "Berlin");
    _dt.Rows.Add("Martin", "Adjei", 45, "London");
    _dt.Rows.Add("Peter", "Moore", 33, "Paris");
    _dt.Rows.Add("Philip", "Gay", 51, "Berlin");
}

private void LoadFilterData()
{
    cb1.Items.AddRange(new string[] { "All", "Berlin", "Accra", "London", "Paris" });
    cb2.Items.AddRange(new string[] { "All", "James", "Martin", "Mike", "Peter", "Philip", "Simon" });
    cb3.Items.AddRange(new string[] { "All", "Brown", "Gay", "Black", "Adjei", "Moore" });
    // Fill age filter comboboxes
    for (int i = 0; i <= 100; i++)
    {
        cbFilterAgeFrom.Items.Add(i);
        cbFilterAgeTo.Items.Add(i);
    }
}

private void cb1_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterData();
}

private void cb2_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterData();
}

private void cb3_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterData();
}

private void cbFilterAgeFrom_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterData();
}

private void cbFilterAgeTo_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterData();
}

private void FilterData()
{
    DataView dv = new DataView(_dt);

    var cityFilter = string.IsNullOrWhiteSpace(cb1.Text) ? "All" : cb1.Text.Trim();
    var fNameFilter = string.IsNullOrWhiteSpace(cb2.Text) ? "All" : cb3.Text.Trim();
    var lNameFilter = string.IsNullOrWhiteSpace(cb3.Text) ? "All" : cb2.Text.Trim();
    // Get values for age filter
    var ageFromFilter = string.IsNullOrWhiteSpace(cbFilterAgeFrom.Text) ? 0 : (int)cbFilterAgeFrom.SelectedItem;
    var ageToFilter = string.IsNullOrWhiteSpace(cbFilterAgeTo.Text) ? 0 : (int)cbFilterAgeTo.SelectedItem;

    // Make list for keeping single filter values
    var filterItems = new List<string>();
    if (cityFilter != "All")
    {
        filterItems.Add(string.Format(" [City] = '{0}'", cityFilter));
    }
    if (fNameFilter != "All")
    {
        filterItems.Add(string.Format(" [FName] = '{0}'", fNameFilter));
    }
    if (lNameFilter != "All")
    {
        filterItems.Add(string.Format(" [LName] = '{0}'", lNameFilter));
    }
    if (ageFromFilter > 0)
    {
        filterItems.Add(string.Format(" [Age] >= {0}", ageFromFilter));
    }
    if (ageToFilter > 0)
    {
        filterItems.Add(string.Format(" [Age] <= {0}", ageToFilter));
    }

    // If there are filter items on the list we will join them into one string
    if (filterItems.Count > 0)
    {
        var filter = string.Join(" AND ", filterItems);
        // You can remove this line, it is just for 'debugging' purposes :)
        MessageBox.Show(filter);
        dv.RowFilter = filter;
    }
    dataGridView1.DataSource = dv;
}





有关RowFilter的更多信息,请点击此处:

[]



[更新 - 回答评论]

如果您有更多的过滤条件,那么解决方案比我之前的更简单。我认为过滤年龄最好在两个值(from-to)之间进行过滤,而不是搜索精确值。所以我修改了我的答案,你应该采取一些步骤:

cb1 - >城市组合过滤器

cb2 - >名字的组合过滤器

cb3 - >姓氏的组合过滤器

为年龄过滤添加两个组合框:

cbFilterAgeFrom cbFilterAgeTo - >过滤器时代的组合From-To



不要忘记为新的ComboBox绑定 SelectedIndexChanged 事件处理程序。



小解释这里发生了什么:

1.我们正在声明List< string>保留单个字段的过滤值。如果您选择了City(即柏林)和AgeTo(即27),那么我们的列表将包含以下值:

[City] ='Berlin'

[年龄]< = 27


2.在方法 FilterData 和我们正在检查列表是否包含一些项目。如果是,那么我们将加入它们以获得所有 filterItems 的一个字符串,并且我们正在添加'AND'运算符。最后我们得到这样的结果:

[城市] ='柏林'和[年龄]< = 27



和一些链接:

[]

[]



我希望你会发现这个有用:)



More informations about RowFilter you can find here:
http://www.csharp-examples.net/dataview-rowfilter/[^]

[Update - Answer for comment]
If you have more filter conditions there is a little bit simpler solution than my previous. I think that filtering age is better to filter between two values (from-to) than searching for exact value. So I've modified my answer and you should take some steps:
cb1 -> Combo filter for Cities
cb2 -> Combo filter for First names
cb3 -> Combo filter for Last names
Add two comboboxes for age filtering:
cbFilterAgeFrom, cbFilterAgeTo -> Combo for filter age From-To

Don't forget to bind SelectedIndexChanged event handler for new ComboBoxes.

Little explanation what is going here:
1. We are declaring List<string> to keep filter values for single fields. If you have selected City (i.e. Berlin) and AgeTo (i.e. 27) then our list will contain values like this:
[City] = 'Berlin'
[Age] <= 27

2. At the and of method FilterData we are checking if list contains some items. If yes, then we are joining them to get one string for all filterItems and we are adding 'AND' operator. So finally we get something like this:
[City] = 'Berlin' AND [Age] <= 27

And some links:
String.Join method[^]
Collections in .NET[^]

I hope you will find this useful :)


这篇关于基于两个comboboex过滤DGV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 17:51