M
michael sorens
I have seen a few posts in the forums regarding column order of a
DataGridView. I also ran into an issue involving this and thought I would
pass along my scenario and its solution in case it might be of use to the
community.
I have an application that uses a RichTextBox and a DataGridView as a simple
database query tool. As such, the DataGridView has no columns or associated
data set when the program starts up, and the AutoGenerateColumns property is
true. The user may enter an arbitrary query and the result set dynamically
defines and populates the DataGridView.
The problem was this:
(1) Execute a query which begins "select a, b from... "
(2) Observe DataGridView columns in this order: a, b
(3) Change the query to begin "select c, a, b from..." and execute it.
(4) Observe DataGridView columns in this order: a, b, c rather than c, a, b
(5) Make no changes and execute again.
(6) Observe DataGridView columns now in this order: c, a, b
So it takes an extra refresh of the same query to get the DataGridView to
put columns in the correct order! This is 100% reproducible behavior.
I then attempted to create a smaller project to isolate this issue. With
essentially the same code the behavior in this test program was different:
At step 6 the columns remain in the wrong order and stay that way no matter
how many times the query is executed. For this project, this is 100%
reproducible behavior.
Both of these use essentially the same code. First the BAD code:
qDataGridView.BindingSource = qBindingSource;
DataTable dataTable = new DataTable();
SqlDataAdapter tableAdapter =
new SqlDataAdapter(queryString, myConnectionString);
try { tableAdapter.Fill(dataTable); }
catch (SqlException ex) { /* handle exception... */ }
qBindingSource.DataSource = dataTable;
qBindingSource.DataMember = null;
And now the GOOD code:
qDataGridView.BindingSource = qBindingSource;
DataTable dataTable = new DataTable();
SqlDataAdapter tableAdapter =
new SqlDataAdapter(queryString, myConnectionString);
qBindingSource.DataSource = dataTable;
qBindingSource.DataMember = null;
try { tableAdapter.Fill(dataTable); }
catch (SqlException ex) { /* handle exception... */ }
The fix, as you will observe, is that the Fill() method must be called
*after* the DataTable is assigned to the binding source's DataSource
property. I am not sure why the two projects yielded different results with
the same bad code, but they both are corrected with the good code.
I am not enough of a subject matter expert to state categorically, but this
seems like a bug in the framework code to me...
DataGridView. I also ran into an issue involving this and thought I would
pass along my scenario and its solution in case it might be of use to the
community.
I have an application that uses a RichTextBox and a DataGridView as a simple
database query tool. As such, the DataGridView has no columns or associated
data set when the program starts up, and the AutoGenerateColumns property is
true. The user may enter an arbitrary query and the result set dynamically
defines and populates the DataGridView.
The problem was this:
(1) Execute a query which begins "select a, b from... "
(2) Observe DataGridView columns in this order: a, b
(3) Change the query to begin "select c, a, b from..." and execute it.
(4) Observe DataGridView columns in this order: a, b, c rather than c, a, b
(5) Make no changes and execute again.
(6) Observe DataGridView columns now in this order: c, a, b
So it takes an extra refresh of the same query to get the DataGridView to
put columns in the correct order! This is 100% reproducible behavior.
I then attempted to create a smaller project to isolate this issue. With
essentially the same code the behavior in this test program was different:
At step 6 the columns remain in the wrong order and stay that way no matter
how many times the query is executed. For this project, this is 100%
reproducible behavior.
Both of these use essentially the same code. First the BAD code:
qDataGridView.BindingSource = qBindingSource;
DataTable dataTable = new DataTable();
SqlDataAdapter tableAdapter =
new SqlDataAdapter(queryString, myConnectionString);
try { tableAdapter.Fill(dataTable); }
catch (SqlException ex) { /* handle exception... */ }
qBindingSource.DataSource = dataTable;
qBindingSource.DataMember = null;
And now the GOOD code:
qDataGridView.BindingSource = qBindingSource;
DataTable dataTable = new DataTable();
SqlDataAdapter tableAdapter =
new SqlDataAdapter(queryString, myConnectionString);
qBindingSource.DataSource = dataTable;
qBindingSource.DataMember = null;
try { tableAdapter.Fill(dataTable); }
catch (SqlException ex) { /* handle exception... */ }
The fix, as you will observe, is that the Fill() method must be called
*after* the DataTable is assigned to the binding source's DataSource
property. I am not sure why the two projects yielded different results with
the same bad code, but they both are corrected with the good code.
I am not enough of a subject matter expert to state categorically, but this
seems like a bug in the framework code to me...