如果列索引 0 包含特定字符串 C#,如何隐藏整个 DataGridview 行

How do I hide an entire DataGridview Row if Column index 0 contains a specific string C#

到目前为止我做了什么

                DataSet dataSet = new DataSet();
                dataSet.ReadXml(dialog.FileName);
                dataGridView1.DataSource = dataSet.Tables[0];

                MessageBox.Show(this.dataGridView1.Columns["Visible"].Index.ToString());//To hide -returns 0
                
                foreach (DataGridViewRow dr in dataGridView1.Rows)
                {
                    if (dr.Cells[0].Value.ToString() == "False")
                    {
                        dr.Visible = false;
                    }
                }

网格视图

我试图隐藏 Visible 列值为 False

的整个行

您可以使用 DataGridView CellPainting 事件。

每次 dataGridView1 中的单元格需要重新绘制时都会触发事件。

好消息是,当 dataGridView1 初始化和用户离开单元格时,将触发此事件。因此,此解决方案将在 DataGridView 初始化时删除任意行(然后删除第 0 列中带有“False”的任何加载行),但也会删除用户在 [=] 期间更改为“False”的任何行27=]时间.

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
   if (e.ColumnIndex < 0 || e.RowIndex < 0)
       return;
   
   if (dataGridView1.Rows[e.RowIndex].Cells[0].Value == null) //Return if cell value is null
       return;

   if (e.ColumnIndex == 0) //Current cell to paint is in visible column
   {
      DataGridViewRow currentRow = dataGridView1.Rows[e.RowIndex]; //Row of current cell
      if (currentRow.Cells[0].Value.ToString() == "False")
      {
         currentRow.Visible = false;
      }
   }
}

在“设计”视图的事件列表中添加事件,或直接将其添加到包含 dataGridView1

的控件的设计器 class
 // 
 // dataGridView1
 // 
...
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(this.dataGridView1_CellPainting);

...

我认为这里的主要问题是您要替换行的 Visible 值,而不是 Datagrid 的行。将 foreach 替换为 for:

for(int i=0; i <= dataGridView1.Rows.Count();i++) {
   dataGridView1.Rows[i].Visible = Convert.ToBoolean(dataGridView1.Rows[i].Cells[0].Value);
}

当您得到该行时,dr.Cells[0].Value.ToString() 的值是多少?使用调试器和 quickwatch 检查它。也许不是你展示的“假”。

主要思想是通过 Convert 获得任何类型的错误。而且你根本不需要 if 。

                if (Convert.ToBoolean(dr.Cells[0].Value))
                {
                    dr.Visible = false;
                }

而且你根本不需要 if。

                    dr.Visible = Convert.ToBoolean(dr.Cells[0].Value);

经过一些研究,我相信您最好“过滤”网格 DataSource 而不是将单个网格行的 Visible 属性 设置为 false.

这样做的最大问题是……您不能将网格 CurrentRow Visible 属性 设置为 false。这将抛出一个异常,沿着…

”Row associated with the currency manager's position cannot be made invisible”

…基本上这就是说网格的CurrentRow不能不可见。

考虑到这一点,似乎这种方法可能行不通,因为网格中至少一 (1) 行将是 CurrentRow,如果网格的 CurrentRow,您的代码将失败“可见”单元格设置为“假”。

此外,为了利用测试参数……如果所有行都是“假”怎么办? …在那种情况下,可以保证异常,因为至少有一行是 CurrentRow.

希望这可以解释“为什么”您的代码有时可以工作而有时却不能。

因此,我提出了一个简单的解决方案,可以完全避免使用网格货币管理器。这可以通过过滤网格 DataSource 来完成。类似于下面的按钮点击事件……

private void button1_Click(object sender, EventArgs e) {
  DataView dv = new DataView(dataSet.Tables[0]);
  dv.RowFilter = "Visible = True";   // <- filter rows that have True in the Visible column
  dataGridView1.DataSource = dv;
}

不清楚您问题中发布的代码在“何处”执行,但是在我上面的解决方案中,如果您将 dataSet 或至少 dataSet.Tables[0] 设置为“全局”,事情会变得更容易多变的。原因是,当您使用 DataView.RowFilter 然后将网格数据源设置为 DataView 时……除非您可以访问原始 table dataset.Tables[0]……否则您将不会能够“取消过滤”网格,而您需要重新查询数据库。我希望这是有道理的。祝你好运。