C#根据多选listBox过滤datagridview
C# Filter datagridview based on multiple selections of listBox
当用户点击我的 datagridview 的其中一列并选择过滤时,会弹出一个 window,其中包含一个列表框,其中填充了该列的值(不重复 - 意思是如果有 5 个 0,它是只显示一次)。
这是弹窗的初始化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;
}
当用户从列表框中选择一个值并按下确定按钮时:
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();
}
其中 CName 是要过滤的列的名称。
效果很好。
但是现在我想在我的列表框中允许多选 属性,这样如果用户选择多个值,我就可以对其进行过滤。我怎样才能做到这一点?是否有必要像我在某些示例中看到的那样使用 "OR"?
根据 DataView.RowFilter and DataColumn.Expression 文档,您可以使用 OR
或 IN
运算符来构建过滤条件,IMO 后者更适合这种情况。
所以代码可能是这样的
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();
}
当用户点击我的 datagridview 的其中一列并选择过滤时,会弹出一个 window,其中包含一个列表框,其中填充了该列的值(不重复 - 意思是如果有 5 个 0,它是只显示一次)。
这是弹窗的初始化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;
}
当用户从列表框中选择一个值并按下确定按钮时:
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();
}
其中 CName 是要过滤的列的名称。
效果很好。
但是现在我想在我的列表框中允许多选 属性,这样如果用户选择多个值,我就可以对其进行过滤。我怎样才能做到这一点?是否有必要像我在某些示例中看到的那样使用 "OR"?
根据 DataView.RowFilter and DataColumn.Expression 文档,您可以使用 OR
或 IN
运算符来构建过滤条件,IMO 后者更适合这种情况。
所以代码可能是这样的
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();
}