问题
In C# WinForms I have two DataGrids displaying tabular data. First display all rows, second one is supposed to display filtered set of these rows. I need to build filtered view on my BindingList view instance. This view needs to be updated, once underlying list is changed.
I've tried to build new BindingList instance with LINQ and Where but the filtered is not updated when underlying myList is changed.
var filtered = new BindingList<Clip>(myList.Where<Clip>
(
c => c.participant.Contains(id)
).ToList<Clip>());
How can I do this? Thanks
回答1:
BindingList<T>
doesn't support filtering (not directly, at least), so I propose to substitute your BindingList with a DataTable. DataView supports filtering and the filtered data is just a custom subset of the same DataTable.
In the example, two BindingSource classes are use to bind the same DataTable to two DataGridView controls.
One of the BindingSource class is bound to a filtered DataView of the DataTable, using the DataView.RowFilter property, an Expression which accepts a subset of SQL-like commands.
Here, the second DataGridView.DataSource
is set to the BindingSource that has its DataSource linked to the filtered DataView
.
The filter is defined using a specific value ("Value A1"
) of the second Column (Column1
).
You can see in the visual sample that the two DataGridView control update their cells values when the cells' values of both the DataGridViews are changed.
Also, the filter is active on the second DataGridView: the rows are filtered when the filtered Column(s) values change.
To test this behaviour, add 2 DataGridView controls to a Form, add a Button (here, named btnBind
) and subscribe to the Click
event with the btnBind_Click
handler.
private BindingSource dgvBindingSource1 = null;
private BindingSource dgvBindingSource2 = null;
private DataTable dt = null;
private void btnBind_Click(object sender, EventArgs e)
{
FillData(3, 3);
dgvBindingSource1 = new BindingSource(dt, null);
DataView dv = dt.AsDataView();
dv.RowFilter = "Column1 = 'Value A1'";
dgvBindingSource2 = new BindingSource(dv, null);
dataGridView1.DataSource = dgvBindingSource1;
dataGridView2.DataSource = dgvBindingSource2;
}
private void FillData(int cols, int rows)
{
dt = new DataTable("TestTable");
dt.Columns.AddRange(Enumerable.Range(0, cols)
.Select(i => new DataColumn("Column" + i.ToString(), typeof(string))).ToArray());
for (int r = 0; r < rows; r++) {
dt.Rows.Add(Enumerable.Range(0, cols)
.Select(n => $"Value {(char)('A' + r)}" + n.ToString()).ToArray());
}
}
来源:https://stackoverflow.com/questions/55746869/filtering-bindinglist