【问题标题】:How can I set the position of my datagrid scrollbar in my winforms app?如何在我的 winforms 应用程序中设置我的 datagrid 滚动条的位置?
【发布时间】:2010-09-27 13:24:51
【问题描述】:

在我的 C# winforms 应用程序中,我有一个数据网格。当数据网格重新加载时,我想将滚动条设置回用户设置的位置。我该怎么做?

编辑:我使用的是旧的 winforms DataGrid 控件,而不是较新的 DataGridView

【问题讨论】:

    标签: c# winforms datagrid


    【解决方案1】:

    您实际上并没有直接与滚动条交互,而是设置了FirstDisplayedScrollingRowIndex。因此,在重新加载之前,捕获该索引,一旦重新加载,将其重置为该索引。

    编辑:评论中的要点。如果您使用的是DataGridView,那么这将起作用。如果您使用旧的DataGrid,那么最简单的方法就是继承它。见这里:Linkage

    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));
        }
    }
    

    【讨论】:

    • 我正在使用旧的 DataGrid 控件
    • 我仍在使用旧的 DataGrid :) ,该链接完美地回答了它。但我担心,链接不会持续很长时间,因为它已经超过 4 年了,我在这里重新发布答案以供将来参考。
    • 那些需要知道第一个可见DataGrid行的索引的人:请看我下面的帖子。
    【解决方案2】:

    是的,绝对是FirstDisplayedScrollingRowIndex。您需要在一些用户交互后捕获此值,然后在重新加载网格后,您需要将其设置回旧值。

    例如,如果重新加载是由单击按钮触发的,那么在按钮单击处理程序中,您可能希望在第一行中包含一个将该值放入变量的命令:

    // Get current user scroll position
    int scrollPosition = myGridView.FirstDisplayedScrollingRowIndex;
    
    // Do some work
    ...
    
    // Rebind the grid and reset scrolling
    myGridView.DataBind;
    myGridView.FirstDisplayedScrollingRowIndex = scrollPosition;
    

    【讨论】:

      【解决方案3】:

      将您的垂直和水平滚动值存储到某个变量中并重置它们。

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

      【讨论】:

      • Horizo​​ntalScrollingOffset 和 VerticalScrollingOffset 没有设置器
      • 仍然有效(.NET 4.5.1)
      • VerticalScrollingOffset 是只读的 (VB.NET 4.5.2) 但HorizontalScrollingOffset 是我所需要的,而且效果很好。
      【解决方案4】:

      刚刚把答案贴在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
      

      【讨论】:

        【解决方案5】:

        你可以用下一个代码保存滚动位置


        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); 
        

        【讨论】:

        • 所有 User32.dll 的东西都不能与 DataGridView 一起使用,但你的属性魔法有效,谢谢。这应该是公认的答案。
        【解决方案6】:

        我使用了@BFree 的答案,但还需要捕获DataGrid 中的第一个可见行:

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

        【讨论】:

          【解决方案7】:

          尽管这是一个老问题,但上面的许多解决方案都对我不起作用。最终奏效的是:

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

          【讨论】:

            猜你喜欢
            • 2011-07-03
            • 1970-01-01
            • 2011-07-05
            • 1970-01-01
            • 2011-10-31
            • 1970-01-01
            • 2012-01-21
            • 2015-07-13
            • 2013-10-16
            相关资源
            最近更新 更多