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

Posted

技术标签:

【中文标题】如果列索引 0 包含特定字符串 C#,如何隐藏整个 DataGridview 行【英文标题】:How do I hide an entire DataGridview Row if Column index 0 contains a specific string C# 【发布时间】:2021-12-07 13:03:44 【问题描述】:

到目前为止我做了什么

                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 的整个行

【问题讨论】:

@LeandroBardelli "False" 查看我的答案更新 为什么不把它隐藏在数据源中呢?通过不检索这些行?还是在数据集中过滤? 【参考方案1】:

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

这样做的最大问题是您不能将网格CurrentRowVisible 属性设置为false。这将抛出一个异常,抱怨...

“与货币经理职位相关的行不能隐藏”

...基本上这是说网格的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] 设为“GLOBAL”变量,事情会变得更容易。原因是当您使用 DataView.RowFilter 并将网格数据源设置为 DataView... 时,除非您有权访问原始表 dataset.Tables[0]... 您将无法“取消过滤”网格并且相反,您需要重新查询数据库。我希望这是有道理的。祝你好运。

【讨论】:

【参考方案2】:

我认为这里的主要问题是您要替换行的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() 的值是多少?使用调试器和快速监视检查它。也许不是你展示的“假”。

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

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

而且你根本不需要 if。

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

【讨论】:

【参考方案3】:

您可以使用DataGridView CellPainting 事件。

每当dataGridView1 中的单元格需要重新绘制时,就会触发该事件。

好消息是当dataGridView1 被初始化并且当用户离开一个单元格时这个事件将被触发。因此,此解决方案将在 DataGridView 初始化时删除任意行(然后删除第 0 列中带有“False”的任何已加载行),但还会删除在运行时由用户更改为“False”的任何行。

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的控件的设计器类中

 // 
 // dataGridView1
 // 
...
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(this.dataGridView1_CellPainting);

...

【讨论】:

以上是关于如果列索引 0 包含特定字符串 C#,如何隐藏整个 DataGridview 行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 FactoMineR 包以编程方式确定主成分的列索引?

基于列索引的 Spark Dataframe 选择

2 列索引与 3 列索引的性能方面

如何通过C#中的特定片段从句子中提取整个单词?

低基数列索引 VS 表开销

如何在 Pandas 中选择某些列索引(连续和单独)