Reputation: 249
When the user clicks on one of my datagridview's columns and chooses to filter, a window pops up with a listbox which is populated with that column's values (not repetitive- meaning if there are 5 0's it is only shown once).
This is the initialization of the popup window.
public partial class ComboBoxFilter : Form
{
DataGridView Dgv;
DataGridViewColumn Col;
DataView View;
string CName;
public ComboBoxFilter(DataGridView dgv, DataGridViewColumn col, DataView view, string colName)
{
InitializeComponent();
Dgv = dgv;
Col = col;
View = view;
CName = colName;
listBox1.ValueMember = col.DataPropertyName;
listBox1.DisplayMember = col.DataPropertyName;
DataTable dt = view.ToTable(true, new string[] { col.DataPropertyName });
dt.DefaultView.Sort = col.DataPropertyName;
listBox1.ClearSelected();
listBox1.DataSource = dt;
}
When user selects one value from listbox and pushes OK button:
private void buttonOK_Click(object sender, EventArgs e)
{
BindingSource bs = (BindingSource)Dgv.DataSource;
bs.Filter = string.Format("{0} = '{1}'", CName, listBox1.SelectedValue.ToString());
Dgv.DataSource = bs;
this.Close();
}
Where CName is the column's to be filtered name.
This works great.
However now I would like to allow multiselect property on my listbox, so that if the user selects multiple values, I can filter for that. How can I do this? Is it necessary to use "OR" like I've seen in some examples?
Upvotes: 0
Views: 1017
Reputation: 205849
According to the DataView.RowFilter and DataColumn.Expression documentation, you can use OR
or IN
operators to build the filter criteria, with IMO the later being more appropriate for this scenario.
So the code could be something like this
private void buttonOK_Click(object sender, EventArgs e)
{
var selection = string.Join(",", listBox1.SelectedItems.Cast<object>()
.Select(item => "'" + listBox1.GetItemText(item) + "'").ToArray());
var filter = listBox1.SelectedItems.Count == 0 ? string.Empty :
listBox1.SelectedItems.Count == 1 ? string.Format("{0} = {1}", CName, selection) :
string.Format("{0} IN ({1})", CName, selection);
var bs = (BindingSource)Dgv.DataSource;
bs.Filter = filter;
this.Close();
}
Upvotes: 1