简体   繁体   中英

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

What I've done so far

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

The gridview 在此处输入图像描述

I'm trying to hide the entire Row where the Visible Column value is False

You may use the DataGridView CellPainting event.

Everytime a cell in dataGridView1 needs repainting the event is fired.

The good thing is that this event will fire when the dataGridView1 is initialized and when the user leaves a cell. Hence this solution will remove the arbitrary rows when the DataGridView is initializing (and then remove any loaded rows with "False" in column 0) but also remove any rows that are changed to "False" by the user during run time.

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

Either add the event at the events list in the Design view or add it directly to the designer class for the control containing dataGridView1

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

...

The main problem here, I think, is that you are replacing the Visible value of the row, instead of the row of the Datagrid. Replace the foreach with a for :

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

What is the value of dr.Cells[0].Value.ToString() when you get that row? Check it with debugger and quickwatch. Maybe is not "False" as you show it.

The main idea is get any kind of false with Convert. And also you don't need the if at all.

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

And also you don't need the if at all.

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

After some research, I am confident that you will be better off “filtering” the grids DataSource as opposed to setting the individual grid row's Visible property to false.

The biggest problem you will have in doing this… is that you CAN NOT set the grids CurrentRow Visible property to false . This will throw an exception that complains along the lines of …

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

… basically this is saying the grid's CurrentRow cannot be invisible.

Considering this, it would appear that this approach may not work since at least ONE (1) row in the grid will be the CurrentRow and your code will fail if the grid's CurrentRow “Visible” cell is set to “False.”

In addition, to exploit the testing parameters… what if ALL the rows are “False”? … In that case the exception is guaranteed since at least ONE of the rows will be the CurrentRow .

Hopefully, this may explain “why” your code may work some times and not at other times.

Therefore, I suggest a simple solution that avoids the grids currency manager all together. This can be done by filtering the grids DataSource . Something like the button click event below…

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

It is unclear “where” the posted code in your question is executed, however in my solution above it will make things easier if you make dataSet or at least dataSet.Tables[0] a “GLOBAL” variable. Reason being that when you use the DataView.RowFilter and then set the grids data source to the DataView … then unless you have access to the original table dataset.Tables[0] … you will not be able to “un-filter” the grid and instead you would need to re-query the DB. I hope that makes sense. Good Luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM