Question

I have seen a lot of posts on SO about weird behaviour of Columns and their visibility in particular when refreshing the grid and dynamically building the columns in the list, but haven't found a satisfactory solution.

After some digging I am almost certain this issue is due to the use of the DataGridView.Columns.Clear() method.

So far I haven't been able to work out why but removing the Clear() method when I dynamically build my DataGridView Columns stops hidden columns from appearing, but I don't understand why this would have any affect? Surely if you clear the Columns collection and use DataGridView.Columns.Add() to start adding new ones, code like;

dataGridView1.Columns.Clear(); // This is the offending method!!

dataGridView1.AutoGenerateColumns = false;
dataGridView1.ShowEditingIcon = false;
dataGridView1.RowHeadersVisible = false;

DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.DataPropertyName = "ID";
col.HeaderText = "ID";
col.Visible = false; // Notice the visibility of this column...
dataGridView1.Columns.Add(col);

... // Code is repeated for other columns in the collection

I can't see anything wrong with but if dataGridView1.Columns.Clear(); is included at the beginning my hidden column becomes visible, surely this is a bug?

Était-ce utile?

La solution

I was able to reproduce the issue. The Clear method call is just fine, you can remove columns one by one and the issue still persists. The "offending" call is surprisingly Add:

col.Visible = false; // Notice the visibility of this column...
if (col.Visible)
{
   // Just to be sure. Never get here.
}
dataGridView1.Columns.Add(col);
if (col.Visible)
{
   // Surprise! We are here.
}

Why this behavior occurs?

It's definitely a bug. The issue is happening only and only if all the following conditions are met:

  1. DataGridView is in bound mode, i.e. has DataSource set. The data source type doesn't matter.
  2. Columns collection is empty
  3. Add method is called with a column having Visible = false

In this case the code hits an internal class DataGridViewDataConnection method MatchCurrencyManagerPosition. Take a look at the source code, especially the

// Treat case where columnIndex == -1. We change the visibility of the first column.

comment and the code block after that comment.

How to avoid it

To recap, this is happening only in data bound mode and only for the first added column if it is set to be hidden.

So there are a couple ways to fix that:

  1. Make sure the grid is not in bound mode when repopulating columns

    var dataSource = dataGridView.DataSource;
    dataGridView.DataSource = null;
    // Repopulate columns
    //...
    dataGridView.DataSource = dataSource;
    
  2. Don't use Add method. Create all columns and keep them in either variables or temporary list, and at the end use the AddRange method which has no such effect.

  3. Do not set Visible = false in advance. Create and add all the columns, then hide the desired ones.

Autres conseils

This is due to the datatable's DefaultView being directly set as gridview's datasource.

We should set datasource property to DefaultView.ToTable() because whenever datatable is Cleared or Reset, then it clears metadata and hence loses the visibility information of grid.

Now this is really unidentified why reseting datatable information affects DataGridViewColumn's visibility.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top