DataGridView.AutoResizeRows bug?

A

andy.emmerich

I'm breaking in .net 2.0 here at work and have run across some strange
behavior (or lack thereof) with the DataGridView's AutoResizeRows
function, and its little brother AutoResizeRow(int). I'm hoping that
somebody can give me a workaround, or at least verify whether or not
this is a bug.

The executive summary: AutoResizeRow does not work immediately after I
manually add unbound rows to a DataGridRowView, even through their
image content is taller than the default row height. The rows stay the
same hight no matter how many times I call AutoResizeRow in the time
before the DGV is drawn. Later calls to AutoResizeRow which are
initiated by the user work properly.

The application displays, among other things, a person's name, a
selectable drink combo box, a picture of their selected drink, and a
"Drink!" button which makes them increasingly drunk. When the
application starts, I'm building up three (unbound) rows manually.

private void PopulateGrid_()
{
DataGridViewRow CurrentRow =
dgvDrinkers.Rows[dgvDrinkers.Rows.Add()];
CurrentRow.Cells[DStr_(EDrinkersCols.DrinkerName)].Value =
"Andy";
CurrentRow.Cells[DStr_(EDrinkersCols.Liquor)].Value =
EDrinks.Wine.ToString();

CurrentRow = dgvDrinkers.Rows[dgvDrinkers.Rows.Add()];
CurrentRow.Cells[DStr_(EDrinkersCols.DrinkerName)].Value =
"Adam";
CurrentRow.Cells[DStr_(EDrinkersCols.Liquor)].Value =
EDrinks.Beer.ToString();

CurrentRow = dgvDrinkers.Rows[dgvDrinkers.Rows.Add()];
CurrentRow.Cells[DStr_(EDrinkersCols.DrinkerName)].Value =
"Edgar";
}

In order to populate with default values, I'm handling the RowsAdded
event like so:

void dgvDrinkers_RowsAdded(object sender,
DataGridViewRowsAddedEventArgs e)
{
DataGridViewRow addedRow = dgvDrinkers.Rows[e.RowIndex];
addedRow.Cells[DStr_(EDrinkersCols.Liquor)].Value =
EDrinks.Water.ToString();
}

The tricky bit is that this DGV has an Image Column in it that displays
a picture of the drink specified in the Liquor column. I'm setting
that with a CellValueChanged handler:

void dgvDrinkers_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
if (IsNonHeaderComboBoxColumn(e))
SetRowImage(e.RowIndex); // sets the image
column value based on the Liquor column
}

Since the picture is going to be kind of tall, I want to resize all
these rows I added. SetRowImage sets the value of the ImageCell in the
changed row to the appropriate resource and then calls
AutoResizeRow(e.RowIndex). However, when I start the application, the
three rows are set to their default height (about 22 pixels) even
though the images displayed are around 100 pixels tall. AutoResizeRow
DID NOT work.

If I choose a different Liquor at this point, SetRowImage is called
again, and the row resizes appropriately. I also tried this:

public frmDataGridViewForm()
{
InitializeComponent();
InitDgvDrinkers_(); // set up data grid view columns
PopulateGrid_(); // set up the three initial rows
dgvDrinkers.AutoResizeRows(); // this doesn't have any
effect, either!
}

If I try to resize after grid population is complete, I get the same
result, i.e. nothing happens.

I found one extremely weird thing when I turned on my autos window in
Visual Studio '05 and set a break at the form constructor's
AutoResizeRows line. I wanted to watch the height of one of the rows,
so I expanded the DGV's Rows.Items[0] object. Before the resize call,
the height was 22, and after I stepped through, the height went to 106,
and when I continued, all the rows were the right size! I repeated
this test but instead set the break AFTER the Resize call, and the
erroneous behavior returned - no change whatsoever in row height.

Something about one of the DGV property gets in the Autos window must
have triggered the correct resize action, but I don't have a clue how
to reproduce the effect at runtime. I've scattered AutoResizeRows
throughout the app and haven't so far been able to get it to resize.
It's possible that the DGV controls haven't yet been created when I'm
calling AutoResize, so I may try to create a timer that fires soon
after initialization and see if a resize then will have any effect.
Even so, that seems like an awful hack.

Anybody got any ideas?
 
A

Apoxy

Here's what I've learned with a bit more poking:

* Setting a timer to fire AutoResizeRows() after any amount of time
following grid population works.

* Setting the grid's AutoSizeRowsMode =
DataGridViewAutoSizeRowsMode.DisplayedCells also works properly - you
never have to call AutoResizeRows at all if you've got this set. I
don't know how well that solution scales, though; I guess if they set
it up correctly it should only adversely affect users with
exceptionally large grids and excetionally slow computers.


I'm breaking in .net 2.0 here at work and have run across some strange
behavior (or lack thereof) with the DataGridView's AutoResizeRows
function, and its little brother AutoResizeRow(int). I'm hoping that
somebody can give me a workaround, or at least verify whether or not
this is a bug.

The executive summary: AutoResizeRow does not work immediately after I
manually add unbound rows to a DataGridRowView, even through their
image content is taller than the default row height. The rows stay the
same hight no matter how many times I call AutoResizeRow in the time
before the DGV is drawn. Later calls to AutoResizeRow which are
initiated by the user work properly.

The application displays, among other things, a person's name, a
selectable drink combo box, a picture of their selected drink, and a
"Drink!" button which makes them increasingly drunk. When the
application starts, I'm building up three (unbound) rows manually.

private void PopulateGrid_()
{
DataGridViewRow CurrentRow =
dgvDrinkers.Rows[dgvDrinkers.Rows.Add()];
CurrentRow.Cells[DStr_(EDrinkersCols.DrinkerName)].Value =
"Andy";
CurrentRow.Cells[DStr_(EDrinkersCols.Liquor)].Value =
EDrinks.Wine.ToString();

CurrentRow = dgvDrinkers.Rows[dgvDrinkers.Rows.Add()];
CurrentRow.Cells[DStr_(EDrinkersCols.DrinkerName)].Value =
"Adam";
CurrentRow.Cells[DStr_(EDrinkersCols.Liquor)].Value =
EDrinks.Beer.ToString();

CurrentRow = dgvDrinkers.Rows[dgvDrinkers.Rows.Add()];
CurrentRow.Cells[DStr_(EDrinkersCols.DrinkerName)].Value =
"Edgar";
}

In order to populate with default values, I'm handling the RowsAdded
event like so:

void dgvDrinkers_RowsAdded(object sender,
DataGridViewRowsAddedEventArgs e)
{
DataGridViewRow addedRow = dgvDrinkers.Rows[e.RowIndex];
addedRow.Cells[DStr_(EDrinkersCols.Liquor)].Value =
EDrinks.Water.ToString();
}

The tricky bit is that this DGV has an Image Column in it that displays
a picture of the drink specified in the Liquor column. I'm setting
that with a CellValueChanged handler:

void dgvDrinkers_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
if (IsNonHeaderComboBoxColumn(e))
SetRowImage(e.RowIndex); // sets the image
column value based on the Liquor column
}

Since the picture is going to be kind of tall, I want to resize all
these rows I added. SetRowImage sets the value of the ImageCell in the
changed row to the appropriate resource and then calls
AutoResizeRow(e.RowIndex). However, when I start the application, the
three rows are set to their default height (about 22 pixels) even
though the images displayed are around 100 pixels tall. AutoResizeRow
DID NOT work.

If I choose a different Liquor at this point, SetRowImage is called
again, and the row resizes appropriately. I also tried this:

public frmDataGridViewForm()
{
InitializeComponent();
InitDgvDrinkers_(); // set up data grid view columns
PopulateGrid_(); // set up the three initial rows
dgvDrinkers.AutoResizeRows(); // this doesn't have any
effect, either!
}

If I try to resize after grid population is complete, I get the same
result, i.e. nothing happens.

I found one extremely weird thing when I turned on my autos window in
Visual Studio '05 and set a break at the form constructor's
AutoResizeRows line. I wanted to watch the height of one of the rows,
so I expanded the DGV's Rows.Items[0] object. Before the resize call,
the height was 22, and after I stepped through, the height went to 106,
and when I continued, all the rows were the right size! I repeated
this test but instead set the break AFTER the Resize call, and the
erroneous behavior returned - no change whatsoever in row height.

Something about one of the DGV property gets in the Autos window must
have triggered the correct resize action, but I don't have a clue how
to reproduce the effect at runtime. I've scattered AutoResizeRows
throughout the app and haven't so far been able to get it to resize.
It's possible that the DGV controls haven't yet been created when I'm
calling AutoResize, so I may try to create a timer that fires soon
after initialization and see if a resize then will have any effect.
Even so, that seems like an awful hack.

Anybody got any ideas?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top