Reputation: 6514
For scrolling the datagrid, I use following code:
dataGridView1.FirstDisplayedScrollingRowIndex = currentRowIndexInGridView;
dataGridView1.Update();
That works fine for rows not at the bottom of the grid. If I use it for bottom rows, the setter doesnt set it to the value I wanted, when I inspect it during debugging. E.g. I am setting FirstDisplayedScrollingRowIndex= 103, but after the assignment FirstDisplayedScrollingRowIndex has the value 90 and hence the desired row is not visible. From a certain point it stops scrolling and I cant see the last 5 rows. If I am adding new rows and setting them to be displayed, it scrolls by one, but I dont see the last 5 rows again.
I think it has something to do with the fact, the some of my rows have different height and some internal estiment of DisplayedRowCount fails ???
Is there a way of detecting this situation and then forcing scrolling to the bottom of the datagrid?
EDIT:
The important part of the FirstDisplayedScrollingRowIndex setter looks like this in the Reflector:
if (value > this.displayedBandsInfo.FirstDisplayedScrollingRow)
{
int rows = this.Rows.GetRowCount(DataGridViewElementStates.Visible, this.displayedBandsInfo.FirstDisplayedScrollingRow, value);
this.ScrollRowsByCount(rows, (rows > 1) ? ScrollEventType.LargeIncrement : ScrollEventType.SmallIncrement);
}
else
{
this.ScrollRowIntoView(-1, value, true, false);
}
There seems to be an error in computing the rows variable.
Upvotes: 4
Views: 8100
Reputation: 1
I have similar issue but I found how to solved. The problem seams to be that DataGridView required windows form refresh and only after that can be set FirstDisplayedScrollingRowIndex to the new index. What I did?
Timer refreshTimer = new Timer();
public void RefreshLog()
{
dataGridViewVesselLog.DataSource = Log.Items;
dataGridViewVesselLog.Update();
dataGridViewVesselLog.Refresh();
refreshTimer.Interval = 100;
refreshTimer.Tick += (s, e) =>
{
if (dataGridViewVesselLog.Rows.Count > 0)
{
foreach (DataGridViewRow r in dataGridViewVesselLog.SelectedRows)
r.Selected = false;
dataGridViewVesselLog.Rows[dataGridViewVesselLog.Rows.Count - 1].Selected = true;
dataGridViewVesselLog.FirstDisplayedScrollingRowIndex = (int)(dataGridViewVesselLog.Rows.Count - 1);
}
refreshTimer.Stop();
}
refreshTimer.Start();
}
Upvotes: 0
Reputation: 6514
I had to force all the rows to have the same width, otherwise the
FirstDisplayedScrollingRowIndex
setter is buggy.
Upvotes: 2
Reputation: 1785
Call following method whenever a new row is added
private void Autoscroll()
{
if (dgv.FirstDisplayedScrollingRowIndex + dgv.DisplayedRowCount(false) < dgv.Rows.Count)
{
dgv.FirstDisplayedScrollingRowIndex += dgv.DisplayedRowCount(false);
}
else
{
dgv.FirstDisplayedScrollingRowIndex = dgv.Rows.Count - 1;
}
}
Upvotes: 2