Reputation: 11101
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
Reputation: 31
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
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
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
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
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
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
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