根据另一个 DataGridView 的行过滤 BindingSource

Filter a BindingSource based on the rows of another DataGridView

我在 Winforms 中有两个 DataGridViews。 DataGrid1 连接到 table,其中包含需要完成的作业列表。一旦有人完成了一项工作,它就会被输入到一个单独的 table 中作为完成,它连接到 DataGrid2。

我需要过滤 DataGrid1 的绑定源,以便当作业在 DataGrid2 中显示为已完成时,它会从 DataGrid1 中过滤掉。我使用的当前代码仅按 DataGrid2 中的最后一个条目过滤绑定源,我需要它按所有条目过滤。

如何根据 DataGrid2 的一列的所有值过滤 DataGrid1 的 BindingSource?

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 = trueCompleted = 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"));