Tomas Grosup
Tomas Grosup

Reputation: 6514

Datagridview FirstDisplayedScrollingRowIndex not working at the bottom of the grid

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

Answers (3)

Borislav Vakrilov
Borislav Vakrilov

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

Tomas Grosup
Tomas Grosup

Reputation: 6514

I had to force all the rows to have the same width, otherwise the

FirstDisplayedScrollingRowIndex

setter is buggy.

Upvotes: 2

Amritpal Singh
Amritpal Singh

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

Related Questions