添加垂直滚动条到面板

54

我想让一个Panel垂直滚动,但不包括水平方向(因此AutoScroll无法使用,因为子控件会超出左边缘)。

那么该如何实现呢?


你想在必要时只有垂直滚动吗?那么将“Scrollbars”属性设置为“Vertical”不起作用吗? - debracey
@debracey 我的 Panel 上没有名为 Scrollbars 的属性,也没有在 Intellisense 中显示。我看到其他人谈论过它,所以我认为它是存在的,但我可能做错了什么。我在这一行代码中得到了这个错误:panel1.Scrollbars = ScrollBars.Vertical; - 'System.Windows.Forms.Panel' 不包含 'Scrollbars' 的定义,并且找不到接受类型为 'System.Windows.Forms.Panel' 的第一个参数的扩展方法 'Scrollbars' (是否缺少使用指令或程序集引用?) - Seth Carnegie
@debracey 我正在使用VS 2010专业版。 - Seth Carnegie
8个回答

51
试试这个方法来实现只垂直滚动。
(在接受更改之前,需要将自动滚动设置为false)
mypanel.AutoScroll = false;
mypanel.HorizontalScroll.Enabled = false;
mypanel.HorizontalScroll.Visible = false;
mypanel.HorizontalScroll.Maximum = 0;
mypanel.AutoScroll = true;

2
非常好的观点,提出了“AutoScroll”需要设置为false的事实,谢谢。 - mschr

33

假设您正在使用winforms,那么默认的面板组件不能为您提供禁用水平滚动组件的方法。解决此问题的一种方法是禁用自动滚动并自己添加滚动条:

ScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Dock = DockStyle.Right;
vScrollBar1.Scroll += (sender, e) => { panel1.VerticalScroll.Value = vScrollBar1.Value; };
panel1.Controls.Add(vScrollBar1);

更详细的讨论请点击此处


我真的不想使用这个“hack”。我该如何手动使用 VScrollBar 组件来完成它? - Seth Carnegie
你所需要做的就是将 VerticalScroll.Value 属性与 Scroll 事件同步。更新了代码。请注意,为了获得滚动效果,面板底部应该有一些元素溢出(即应该有一些不可见的元素可以滚动到)。 - Teoman Soygul
@Teoman,当底部的内容“溢出”时,我该如何使滚动条上的抓手大小随之更改?我刚刚尝试了与您的代码非常相似的代码,但当我向下滚动时,所有内容都会猛烈地晃动,而且无法滚动(即使在那种情况下有东西可以滚动)。 - Seth Carnegie
当我在一个控件上,该控件具有从ScrollabeControl派生的另一个控件,并且我使用滚动条时,ScrollabeControl内部的垂直和水平滚动条会非常快地显示和隐藏(闪烁),而内容似乎无法像自己的滚动条一样平滑滚动。@Microsoft winforms部门:只在控件上拥有一个滚动条有多难! - Mike de Klerk
这根本不起作用...滚动条会随着内容滚动,所以当你向下滚动时,就看不到滚动条上的顶部按钮了。 - Assimilater
显示剩余3条评论

6

AutoScroll实际上是解决方案! 您只需将AutoScrollMargin设置为0, 1000或类似的值,然后使用它向下滚动并在那里添加按钮和项目!


1
请更多地为您的回答提供背景信息,展示一个代码示例等。 - cccnrc

5

Panel有一个AutoScroll属性。只需将该属性设置为True,面板在需要时会自动添加滚动条。


7
OP明确提到“AutoScroll”不是解决方案。 - Neuron

3
以下是实现自定义垂直滚动条的代码。重要的细节在于通过计算添加到面板中的控件消耗了多少空间来确定何时需要滚动条。
panelUserInput.SuspendLayout();
panelUserInput.Controls.Clear();
panelUserInput.AutoScroll = false;
panelUserInput.VerticalScroll.Visible = false;

// here you'd be adding controls

int x = 20, y = 20, height = 0;
for (int inx = 0; inx < numControls; inx++ )
{
    // this example uses textbox control
    TextBox txt = new TextBox();
    txt.Location = new System.Drawing.Point(x, y);
    // add whatever details you need for this control
    // before adding it to the panel
    panelUserInput.Controls.Add(txt);
    height = y + txt.Height;
    y += 25;
}
if (height > panelUserInput.Height)
{
    VScrollBar bar = new VScrollBar();
    bar.Dock = DockStyle.Right;
    bar.Scroll += (sender, e) => { panelUserInput.VerticalScroll.Value =  bar.Value; };
    bar.Top = 0;
    bar.Left = panelUserInput.Width - bar.Width;
    bar.Height = panelUserInput.Height;
    bar.Visible = true;
    panelUserInput.Controls.Add(bar);
}
panelUserInput.ResumeLayout();

// then update the form
this.PerformLayout();

1

三个步骤:

1- 将AutoScroll属性设置为true

2- 在Form的load()方法中添加以下内容:

   my Panel Vertical Scroll Maximum = 10000     

3- 在我的面板控件添加(item)之后添加以下内容: Invalidate();
完成!


0

在Kamgman的答案基础上进行补充,这确实有效。

假设我们将标签作为子控件添加到面板中:

  • 首先添加面板。将AutoScroll设置为True,将AutoSize设置为False。
  • 将标签添加到面板中。将AutoSize设置为true。如果您愿意,可以为其设置MinimumSize以使其至少在水平方向上保持其“形状”。
  • 然后将标签控件的Anchor设置为仅Top。删除其左锚定。这样可以确保标签仅在垂直方向上滚动而不是水平方向上滚动。

如果您选择这种方法,则无需添加隐藏水平滚动条的行。

如果您正在使用System.ComponentModel.ComponentResourceManager.ApplyResources.resx文件中加载它,而不是从.Designer.cs文件中加载,则可能会更好。因为在我的情况下,每当我对此特定表单进行编辑时,我都会失去Designer.cs文件中的更改。但这将取决于您的项目设置方式。


-2
请在您的面板样式代码中添加类似以下内容的代码:

<asp:Panel ID="myPanel" runat="Server" CssClass="myPanelCSS" style="overflow-y:auto; overflow-x:hidden"></asp:Panel>

OP 问了关于 Winforms 的问题(标签里有),我猜这就是你被踩的原因。 - t.durden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接