在我的 C# WinForms 应用程序中,我有一个数据网格。当数据网格重新加载时,我想将滚动条设置回用户上一次的位置。我该如何做?
编辑:我使用的是旧的 WinForms DataGrid 控件,而不是较新的 DataGridView 控件。
编辑:我使用的是旧的 WinForms DataGrid 控件,而不是较新的 DataGridView 控件。
实际上,你并不直接与滚动条交互,而是设置FirstDisplayedScrollingRowIndex
。因此在重新加载之前,捕获该索引,一旦重新加载完成,将其重置为该索引。
编辑:评论中提出了一个很好的观点。如果你正在使用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));
}
}
没错,一定是FirstDisplayedScrollingRowIndex。在某些用户交互后,您需要捕获此值,然后在重新加载网格后,您将希望将其设置回旧值。
例如,如果重新加载是由按钮点击触发的,则在按钮点击处理程序中,您可能希望将此值作为第一行命令放入变量中:
// Get current user scroll position
int scrollPosition = myGridView.FirstDisplayedScrollingRowIndex;
// Do some work
...
// Rebind the grid and reset scrolling
myGridView.DataBind;
myGridView.FirstDisplayedScrollingRowIndex = scrollPosition;
将垂直和水平滚动值存储到某个变量中并重置它们。
int v= dataGridView1.VerticalScrollingOffset ;
int h= dataGridView1.HorizontalScrollingOffset ;
//...reload
dataGridView1.VerticalScrollingOffset = v;
dataGridView1.HorizontalScrollingOffset =h;
VerticalScrollingOffset
是只读的(VB.NET 4.5.2),但我只需要HorizontalScrollingOffset
,这个完美地解决了我的问题。 - SteveCinqint 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);
刚刚在BFree
提供的链接中发布了答案。
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));
}
}
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
if(gridEmployees.FirstDisplayedScrollingRowIndex != -1) gridEmployees.FirstDisplayedScrollingRowIndex = 0;
我使用了@BFree的答案,但还需要捕获DataGrid
中的第一行可见行:
int indexOfTopMostRow = HitTest(dataGrid.RowHeaderWidth + 10,
dataGrid.PreferredRowHeight + 10).Row;