问题描述
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!