筛选绑定列表 [英] Filtering BindingList

查看:108
本文介绍了筛选绑定列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#WinForms中,我有两个显示表格数据的DataGrid。首先显示所有行,第二个应该显示这些行的过滤后的集合。我需要在BindingList视图实例上构建过滤视图。一旦更改了基础列表,就需要更新此视图。



我尝试使用LINQ和
构建新的BindingList实例,但过滤后的不是

  var filter = new BindingList< Clip>(myList.Where< Clip> 

c => c.participant.Contains(id)
).ToList< Clip>());

我该怎么做?
谢谢

解决方案

BindingList< T> 不支持过滤(至少不直接),因此我建议用DataTable替换BindingList。



要测试此行为,请添加2个DataGridView控件到窗体,添加一个按钮(在这里,名为 btnBind ),并使用订阅 Click 事件 btnBind_Click 处理程序。

  private BindingSource dgvBindingSource1 = null; 
private BindingSource dgvBindingSource2 = null;
private DataTable dt = null;

private void btnBind_Click(对象发送者,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());
}
}


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

解决方案

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());
    }
}

这篇关于筛选绑定列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆