ScottG
ScottG

Reputation: 11101

How can I set the position of my datagrid scrollbar in my winforms app?

In my C# winforms app, I have a datagrid. When the datagrid reloads, I want to set the scrollbar back to where the user had it set. How can I do this?

EDIT: I'm using the old winforms DataGrid control, not the newer DataGridView

Upvotes: 33

Views: 70964

Answers (7)


you can save scroll position with next code


int Scroll;
void DataGridView1Scroll(object sender, ScrollEventArgs e)
    {
        Scroll = dataGridView1.VerticalScrollingOffset;
    }

and you can set scroll of dgv to same position after refresing, load dgv... with next code:


PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic | 
BindingFlags.Instance);
verticalOffset.SetValue(this.dataGridView1, Scroll, null); 

Upvotes: 3

GingerBeer
GingerBeer

Reputation: 938

Even though this is an old question, Many of the solutions above did not work for me. What worked ultimately was:

if(gridEmployees.FirstDisplayedScrollingRowIndex != -1) gridEmployees.FirstDisplayedScrollingRowIndex = 0;

Upvotes: 0

Pollitzer
Pollitzer

Reputation: 1620

I used the answer by @BFree, but also needed to capture the first visible row in the DataGrid:

int indexOfTopMostRow = HitTest(dataGrid.RowHeaderWidth + 10, 
                                dataGrid.PreferredRowHeight + 10).Row;

Upvotes: 0

BFree
BFree

Reputation: 103742

You don't actually interact directly with the scrollbar, rather you set the FirstDisplayedScrollingRowIndex. So before it reloads, capture that index, once it's reloaded, reset it to that index.

EDIT: Good point in the comment. If you're using a DataGridView then this will work. If you're using the old DataGrid then the easiest way to do that is to inherit from it. See here: Linkage

The DataGrid has a protected GridVScrolled method that can be used to scroll the grid to a specific row. To use it, derive a new grid from the DataGrid and add a ScrollToRow method.

C# code

public void ScrollToRow(int theRow)
{
    //
    // Expose the protected GridVScrolled method allowing you
    // to programmatically scroll the grid to a particular row.
    //
    if (DataSource != null)
    {
        GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, theRow));
    }
}

Upvotes: 45

Thunder
Thunder

Reputation: 10986

Store your vertical and horizontal scroll values into some variable and reset them.

int v= dataGridView1.VerticalScrollingOffset ;
int h= dataGridView1.HorizontalScrollingOffset ;
//...reload
dataGridView1.VerticalScrollingOffset = v;
dataGridView1.HorizontalScrollingOffset =h; 

Upvotes: 3

Bravo
Bravo

Reputation: 3441

Just posted the answer on the link given by BFree

The DataGrid has a protected GridVScrolled method that can be used to scroll the grid to a specific row. To use it, derive a new grid from the DataGrid and add a ScrollToRow method.

C# code

public void ScrollToRow(int theRow)
{
    //
    // Expose the protected GridVScrolled method allowing you
    // to programmatically scroll the grid to a particular row.
    //
    if (DataSource != null)
    {
        GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, theRow));
    }
}

VB.NET code

Public Sub ScrollToRow(ByVal theRow As Integer)
    '
    ' Expose the protected GridVScrolled method allowing you
    ' to programmatically scroll the grid to a particular row.
    '
    On Error Resume Next

    If Not DataSource Is Nothing Then
        GridVScrolled(Me, New ScrollEventArgs(ScrollEventType.LargeIncrement, theRow))
    End If
End Sub

Upvotes: 2

sfuqua
sfuqua

Reputation: 5853

Yep, definitely FirstDisplayedScrollingRowIndex. You'll need to capture this value after some user interaction, and then after the grid reloads you'll want to set it back to the old value.

For instance, if the reload is triggered by the click of a button, then in the button click handler, you might want to have as your first line a command that places this value into a variable:

// Get current user scroll position
int scrollPosition = myGridView.FirstDisplayedScrollingRowIndex;

// Do some work
...

// Rebind the grid and reset scrolling
myGridView.DataBind;
myGridView.FirstDisplayedScrollingRowIndex = scrollPosition;

Upvotes: 14

Related Questions