Filtering BindingList

老子叫甜甜 提交于 2019-12-25 01:49:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!