【问题标题】:How to Programmatically Scroll a Panel如何以编程方式滚动面板
【发布时间】:2013-07-19 03:29:15
【问题描述】:

我有一个System.Windows.Forms.Panel,里面有一些内容。

我正在尝试以编程方式(垂直)向上或向下滚动面板。

我尝试在面板上将AutoScrollPosition 属性设置为新的Point,但似乎没有这样做。

我将AutoScroll 属性设置为true。

我什至尝试将VerticalScroll.Value 设置为建议的here 的两倍,但这似乎也不起作用。

这就是我目前正在做的事情:

//I have tried passing both positive and negative values.
panel.AutoScrollPosition = new Point(5, 10);

AutoScrollPosition 上的 X 和 Y 值保持为 0 和 0。

对此的任何帮助或指导将不胜感激。

提前致谢,

马旺

【问题讨论】:

  • 您是否尝试在表单底部添加/设置 control.Focus()。
  • AutoScroll 就像它所说的那样,它是 auto。如果您想自己控制滚动,请将其设置回 False。改为设置 AutoScrollMinSize 属性,现在分配 AutoScrollPosition 将起作用。

标签: c# winforms scroll panel


【解决方案1】:

这里有一个解决方案。我想您可以使用Win32Panel 滚动到任意位置,但是这里有一个简单的技巧可以帮助您实现您的要求:

public void ScrollToBottom(Panel p){
  using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
     {
        p.ScrollControlIntoView(c);
        c.Parent = null;
     }
}
//use the code
ScrollToBottom(yourPanel);

或者为了方便使用扩展方法:

public static class PanelExtension {
   public static void ScrollToBottom(this Panel p){
      using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
      {
         p.ScrollControlIntoView(c);
         c.Parent = null;
      }
   }
}
//Use the code
yourPanel.ScrollToBottom();

更新

如果你想设置准确的位置,稍微修改一下上面的代码会有帮助:

//This can help you control the scrollbar with scrolling up and down.
//The position is a little special.
//Position for scrolling up should be negative.
//Position for scrolling down should be positive
public static class PanelExtension {
    public static void ScrollDown(this Panel p, int pos)
    {
        //pos passed in should be positive
        using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + pos })
        {
            p.ScrollControlIntoView(c);                
        }
    }
    public static void ScrollUp(this Panel p, int pos)
    {
        //pos passed in should be negative
        using (Control c = new Control() { Parent = p, Height = 1, Top = pos})
        {
            p.ScrollControlIntoView(c);                
        }
    }
}
//use the code, suppose you have 2 buttons, up and down to control the scrollbar instead of clicking directly on the scrollbar arrows.
int i = 0;
private void buttonUp_Click(object sender, EventArgs e)
{
   if (i >= 0) i = -1;
   yourPanel.ScrollUp(i--);
}
private void buttonDown_Click(object sender, EventArgs e)
{
   if (i < 0) i = 0;
   yourPanel.ScrollDown(i++);
}

您可能想要使用的另一个解决方案是使用Panel.VerticalScroll.Value。但是,我认为您需要进行更多研究才能使其按预期工作。因为我可以看到一旦更改Value,滚动条位置和控制位置不能很好地同步。注意Panel.VerticalScroll.Value 应该在Panel.VerticalScroll.MinimumPanel.VerticalScroll.Maximum 之间。

【讨论】:

  • 感谢您的快速回答。我想我的问题不是很清楚。我正在尝试以编程方式向上或向下滚动面板,而不仅仅是底部。我刚刚编辑了我的问题以反映这一点。对此感到抱歉,但感谢您提供有用的信息。
  • @Marwan 请查看我的更新。
  • 我已经添加了您的代码,并连接了按钮,但面板没有滚动。当我通过代码进行调试时,正在调用您的函数,但面板没有移动。我仍在努力。
  • @Marwanمروان 记得设置AutoScroll = true。我测试了代码,它工作正常。
  • 你是神!你又救了我……非常感谢。在我回来查看您的上一条评论之前,我已经设置了按钮点击来修改面板内容的实际位置......再次感谢!!!
【解决方案2】:

使用@King King Answered Code,如果要隐藏水平和垂直滚动条,只需在构造函数或初始化中应用以下代码即可。

        yourPanel.AutoScroll = false;
        yourPanel.HorizontalScroll.Maximum = 0;
        yourPanel.HorizontalScroll.Visible = false;
        yourPanel.VerticalScroll.Maximum = 0;
        yourPanel.VerticalScroll.Visible = false;
        yourPanel.AutoScroll = true;

【讨论】:

    【解决方案3】:

    如果你有一个派生自Panel的类,那么调用这两个受保护的方法来滚动面板:

    // The bottom is off screen; scroll down. These coordinates must be negative or zero.
    SetDisplayRectLocation(0, AutoScrollPosition.Y - item.BoundingRect.Bottom + ClientRectangle.Bottom);
    AdjustFormScrollbars(true);
    

    在我的示例中,item.BoundingRect.Bottom 是缩略图底部的 Y 坐标,我需要向下滚动面板以使整个缩略图可见。

    @King King 的解决方案是创建一个临时控件,以便可以完成滚动,这对我来说似乎“很重”。而@Hans Passant 设置AutoScrollMinSizeAutoScrollPosition 的建议对我不起作用。

    AutoScroll 保留为其默认值“true”。

    【讨论】:

      【解决方案4】:

      试试这个:- panel.ScrollControlIntoView(childcontrol);

      这应该可行。 childcontrol 是您要在显示区域中显示的特定控件。

      【讨论】:

        【解决方案5】:

        我遇到了一个问题,我无法让我的面板滚动回顶部。我尝试了很多方法来尝试让面板在填充了许多控件后滚动回顶部。

        不管我做了什么,它总是把 VScroll 栏放在底部。

        经过详尽的测试,我发现这是因为我的控件将 TabStop 属性设置为 true(用户控件上的默认设置)导致了问题。

        将 TabStop 设置为 false 修复了它。

        【讨论】:

        • 当您在 stackoverflow 上添加答案并且不确定它是否对某人有用时... 3 年后您只需解决我与用户控件和滚动相关的问题!
        【解决方案6】:

        这出乎意料地有效!注意代码中的减号。设置滚动位置有奇怪的行为。如果将位置设置为精确值 (50),下次读取时它会变为负值 (-50)。所以你必须在设置新的滚动值之前反转它。

        向下滚动:

        private void ButtonScrollDown_OnClick(object sender, EventArgs e)
        {
            Point current = yourScrollPanel.AutoScrollPosition;
            Point scrolled = new Point(current.X, -current.Y + 10);
            yourScrollPanel.AutoScrollPosition = scrolled;
        }
        

        类似地向上滚动,(-current.Y - 10)

        【讨论】:

        • 工作这个? panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X + 200);
        • @Vitokhv:一个甜蜜的捷径。 :)
        • 我有一个需要 X 和 Y 滚动的控件。使用 Point(Math.Abs​​(current.X), -current.Y + 10);而不仅仅是 current.X 让它表现得更好。否则,非滚动坐标将重置回 0(或负数)。
        【解决方案7】:

        创建一个稍微位于可见区域之外的控件(顶部为 -1,clientsize+1),然后调用 ScrollControlIntoView:

        public static class PanelExtension {
        public static void ScrollDown(this Panel p)
        {
        
            using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + 1 })
            {
                p.ScrollControlIntoView(c);                
            }
        }
        public static void ScrollUp(this Panel p )
        {
        
            using (Control c = new Control() { Parent = p, Height = 1, Top = -1})
            {
                p.ScrollControlIntoView(c);                
            }
        }
        }
            //use the code, suppose you have 2 buttons, up and down to control the scrollbar instead of clicking directly on the scrollbar arrows.
        
                private void buttonUp_Click(object sender, EventArgs e)
        {
        
           yourPanel.ScrollUp();
        }
        private void buttonDown_Click(object sender, EventArgs e)
        {
        
           yourPanel.ScrollDown();
        }
        

        with yourpanel.SetAutoScrollMargin(1, 1);您可以设置非常精细的滚动步骤,然后在按钮按下时使用计时器来调用滚动

        【讨论】:

          【解决方案8】:

          设置HorizontalScroll 属性的值,然后使用ScrollControlIntoView 方法对我有用:

          lpanel.HorizontalScroll.Value = 100;
          lpanel.ScrollControlIntoView(lpanel);
          

          【讨论】:

            猜你喜欢
            • 2016-08-29
            • 2014-09-14
            • 2010-12-20
            • 2020-05-25
            • 1970-01-01
            • 2011-07-04
            • 2017-04-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多