Как я могу установить положение полосы прокрутки моей сетки данных в моем приложении winforms?

В моем приложении winforms на С# у меня есть сетка данных. Когда сетка данных перезагружается, я хочу вернуть полосу прокрутки туда, где ее установил пользователь. Как я могу это сделать?

РЕДАКТИРОВАТЬ: я использую старый элемент управления winforms DataGrid, а не более новый DataGridView


person ScottG    schedule 18.12.2008    source источник


Ответы (7)


На самом деле вы не взаимодействуете напрямую с полосой прокрутки, а устанавливаете FirstDisplayedScrollingRowIndex. Поэтому, прежде чем он перезагрузится, зафиксируйте этот индекс, после перезагрузки сбросьте его до этого индекса.

EDIT: Хорошая мысль в комментарии. Если вы используете DataGridView, то это сработает. Если вы используете старый DataGrid, то самый простой способ сделать это — наследоваться от него. См. здесь: связь

DataGrid имеет защищенный метод GridVScrolled, который можно использовать для прокрутки сетки до определенной строки. Чтобы использовать его, создайте новую сетку из DataGrid и добавьте метод ScrollToRow.

Код C#

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));
    }
}
person BFree    schedule 18.12.2008
comment
Я использую старый элемент управления DataGrid. - person ScottG; 18.12.2008
comment
Я все еще использую старый DataGrid :), ссылка отвечает на него идеально. но я боюсь, что ссылка не продлится долго, так как ей уже более 4 лет, я публикую ответ здесь для дальнейшего использования. - person Bravo; 23.07.2012
comment
Тем, кому нужно знать индекс первой видимой строки DataGrid: см. мой пост ниже. - person Pollitzer; 25.01.2017

Да, определенно FirstDisplayedScrollingRowIndex. Вам нужно будет зафиксировать это значение после некоторого взаимодействия с пользователем, а затем, после перезагрузки сетки, вы захотите вернуть старое значение.

Например, если перезагрузка запускается нажатием кнопки, то в обработчике нажатия кнопки вы можете захотеть иметь в качестве первой строки команду, которая помещает это значение в переменную:

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

// Do some work
...

// Rebind the grid and reset scrolling
myGridView.DataBind;
myGridView.FirstDisplayedScrollingRowIndex = scrollPosition;
person sfuqua    schedule 18.12.2008

Сохраните значения вертикальной и горизонтальной прокрутки в некоторой переменной и сбросьте их.

int v= dataGridView1.VerticalScrollingOffset ;
int h= dataGridView1.HorizontalScrollingOffset ;
//...reload
dataGridView1.VerticalScrollingOffset = v;
dataGridView1.HorizontalScrollingOffset =h; 
person Thunder    schedule 29.04.2013
comment
HorizontalScrollingOffset и VerticalScrollingOffset не имеют установщика - person Shahin; 27.11.2013
comment
Тем не менее работает (.NET 4.5.1) - person Mario The Spoon; 12.04.2015
comment
VerticalScrollingOffset доступен только для чтения (VB.NET 4.5.2), но HorizontalScrollingOffset — это все, что мне нужно, и это работает отлично. - person SteveCinq; 31.07.2019

Только что отправил ответ по ссылке, указанной BFree

DataGrid имеет защищенный метод GridVScrolled, который можно использовать для прокрутки сетки до определенной строки. Чтобы использовать его, создайте новую сетку из DataGrid и добавьте метод ScrollToRow.

код С#

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

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
person Bravo    schedule 23.07.2012

Я использовал ответ @BFree, но мне также нужно было захватить первую видимую строку в DataGrid:

int indexOfTopMostRow = HitTest(dataGrid.RowHeaderWidth + 10, 
                                dataGrid.PreferredRowHeight + 10).Row;
person Pollitzer    schedule 25.01.2017

Несмотря на то, что это старый вопрос, многие из приведенных выше решений не сработали для меня. В конечном итоге сработало следующее:

if(gridEmployees.FirstDisplayedScrollingRowIndex != -1) gridEmployees.FirstDisplayedScrollingRowIndex = 0;
person GingerBeer    schedule 21.06.2018


вы можете сохранить позицию прокрутки со следующим кодом


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

и вы можете установить прокрутку dgv в ту же позицию после обновления, загрузить dgv... со следующим кодом:


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