根据另一个 DataGridView 的行过滤 BindingSource
Filter a BindingSource based on the rows of another DataGridView
我在 Winforms 中有两个 DataGridViews
。 DataGrid1 连接到 table,其中包含需要完成的作业列表。一旦有人完成了一项工作,它就会被输入到一个单独的 table 中作为完成,它连接到 DataGrid2。
我需要过滤 DataGrid1 的绑定源,以便当作业在 DataGrid2 中显示为已完成时,它会从 DataGrid1 中过滤掉。我使用的当前代码仅按 DataGrid2 中的最后一个条目过滤绑定源,我需要它按所有条目过滤。
如何根据 DataGrid2 的一列的所有值过滤 DataGrid1 的 BindingSourc
e?
foreach (DataGridViewRow row in dataGrid2.Rows)
{
DataGrid1BindingSource.Filter =
string.Format("ColumnName <> '{0}'", row.Cells[1].Value);
}
这是数据 table 中所有作业的示例,然后是第一个网格包含未完成的作业,第二个网格包含已完成的作业。应显示在未完成网格中的作业是那些不在已完成作业网格中的作业:
__________ ____________ ___________
| All Jobs | | Incomplete | | Completed |
|――――――――――| |――――――――――――| |―――――――――――|
| JobTitle | | JobTitle | | JobTitle |
|――――――――――| |――――――――――――| |―――――――――――|
| Job 1 | | Job 1 | | Job 3 |
| Job 2 | | Job 2 | | Job 4 |
| Job 3 | | | | |
| Job 4 | | | | |
‾‾‾‾‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾‾
在阅读答案之前,您应该知道如果您没有 bool
字段或其他东西来检测哪项工作已完成,那么这不是一个好的设计。您应该有一份工作清单。然后基于 bool
字段,您应该在第一个网格中显示未完成的作业,在第二个网格中显示已完成的作业。然后过滤器将只是 Completed = true
和 Completed = false
.
无论如何,您可以在过滤器表达式中使用IN
。创建一个要在过滤器中使用的值列表就足够了,然后以这种方式创建过滤器:
var ids = this.dataGridView2.Rows.Cast<DataGridViewRow>()
.Where(r => !r.IsNewRow)
.Select(r => r.Cells[0].Value.ToString());
bs1.Filter = string.Format("Column1 NOT IN ({0})", string.Join(",", ids));
在上面的例子中我假设 ids 是 int
所以例如 "Column1 NOT IN (1,2,3)"
将是过滤器。对于字符串 ID,过滤器将为 "Column1 NOT IN ('a','b','c')"
。所以你可以像下面这样更改 select 语句:
.Select(r => string.Format("'{0}'",r.Cells[0].Value.ToString()));
这个片段很丑陋,但它应该给你一个提示:
var colname = YOURGRIDTOFILTER.Columns[INDEXOFCOLUMNTOFILTER].HeaderText;
var filterString = colname+" <> ";
foreach (DataGridViewRow row in dataGrid2.Rows)
{
filterString += "'" + row.Cells[1].Value + "' OR "+colname+" <> ";
}
filterString = filterString.Substring(0, filterString.LastIndexOf("OR"));
我在 Winforms 中有两个 DataGridViews
。 DataGrid1 连接到 table,其中包含需要完成的作业列表。一旦有人完成了一项工作,它就会被输入到一个单独的 table 中作为完成,它连接到 DataGrid2。
我需要过滤 DataGrid1 的绑定源,以便当作业在 DataGrid2 中显示为已完成时,它会从 DataGrid1 中过滤掉。我使用的当前代码仅按 DataGrid2 中的最后一个条目过滤绑定源,我需要它按所有条目过滤。
如何根据 DataGrid2 的一列的所有值过滤 DataGrid1 的 BindingSourc
e?
foreach (DataGridViewRow row in dataGrid2.Rows)
{
DataGrid1BindingSource.Filter =
string.Format("ColumnName <> '{0}'", row.Cells[1].Value);
}
这是数据 table 中所有作业的示例,然后是第一个网格包含未完成的作业,第二个网格包含已完成的作业。应显示在未完成网格中的作业是那些不在已完成作业网格中的作业:
__________ ____________ ___________
| All Jobs | | Incomplete | | Completed |
|――――――――――| |――――――――――――| |―――――――――――|
| JobTitle | | JobTitle | | JobTitle |
|――――――――――| |――――――――――――| |―――――――――――|
| Job 1 | | Job 1 | | Job 3 |
| Job 2 | | Job 2 | | Job 4 |
| Job 3 | | | | |
| Job 4 | | | | |
‾‾‾‾‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾‾
在阅读答案之前,您应该知道如果您没有 bool
字段或其他东西来检测哪项工作已完成,那么这不是一个好的设计。您应该有一份工作清单。然后基于 bool
字段,您应该在第一个网格中显示未完成的作业,在第二个网格中显示已完成的作业。然后过滤器将只是 Completed = true
和 Completed = false
.
无论如何,您可以在过滤器表达式中使用IN
。创建一个要在过滤器中使用的值列表就足够了,然后以这种方式创建过滤器:
var ids = this.dataGridView2.Rows.Cast<DataGridViewRow>()
.Where(r => !r.IsNewRow)
.Select(r => r.Cells[0].Value.ToString());
bs1.Filter = string.Format("Column1 NOT IN ({0})", string.Join(",", ids));
在上面的例子中我假设 ids 是 int
所以例如 "Column1 NOT IN (1,2,3)"
将是过滤器。对于字符串 ID,过滤器将为 "Column1 NOT IN ('a','b','c')"
。所以你可以像下面这样更改 select 语句:
.Select(r => string.Format("'{0}'",r.Cells[0].Value.ToString()));
这个片段很丑陋,但它应该给你一个提示:
var colname = YOURGRIDTOFILTER.Columns[INDEXOFCOLUMNTOFILTER].HeaderText;
var filterString = colname+" <> ";
foreach (DataGridViewRow row in dataGrid2.Rows)
{
filterString += "'" + row.Cells[1].Value + "' OR "+colname+" <> ";
}
filterString = filterString.Substring(0, filterString.LastIndexOf("OR"));