我有一个包含许多小面板的Panel
包含面板的AutoScroll
设置为true,这样当有太多小面板时我可以向下滚动
小面板的宽度始终设置为容器的客户端宽度(允许边框等),因此不应显示水平滚动条。
这似乎主要是这种情况,除非最后一个子面板触摸包含面板的底部,然后当我不想要它时出现水平滚动条!
我已经尝试changing the properties to disable it但这似乎没有效果
我已经尝试always showing the vertical scrollbar(因为这是可以接受的),但它只是简单地显示了一个非常丑陋的酒吧,然后消失了,并被原生的酒吧所取代。
我可以看到other people with the same problem,但没有解决方案。
将下面的代码粘贴到新的Winform中,然后尝试以下步骤:
现在小心地垂直调整表单大小,使最后一个面板的底部接触容器的底部。滚动条应该出现在这里,可能需要一些“摇摆”。
static List<Panel> listOfPanels;
static Panel panel;
static bool flipflop;
private void Form1_Load(object sender, EventArgs e)
{
Height = 400;
Width = 400;
listOfPanels = new List<Panel>();
panel = new Panel()
{
Height = this.ClientSize.Height - 20,
Width = 200,
Top = 10,
Left = 10,
BackColor = Color.White,
BorderStyle = BorderStyle.FixedSingle,
Padding = Padding.Empty,
Margin = Padding.Empty,
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom,
};
// I'VE TRIED DISABLING IT HERE!
panel.AutoScroll = false;
panel.HorizontalScroll.Enabled = false;
panel.HorizontalScroll.Visible = false;
panel.AutoScroll = true;
panel.Resize += panel_Resize;
Button button = new Button()
{
Text = @"Add",
Size = new Size(100, 50),
Top = 10,
Left = 20 + panel.Width
};
button.Click += button_Click;
Controls.Add(panel);
Controls.Add(button);
}
void panel_Resize(object sender, EventArgs e)
{
renderSubPanels();
}
void button_Click(object sender, EventArgs e)
{
Panel subPanel = new Panel()
{
Height = 100,
BackColor = flipflop ? Color.PeachPuff : Color.PowderBlue,
Top = (listOfPanels.Count * 100) - Math.Abs(panel.AutoScrollPosition.Y)
};
listOfPanels.Add(subPanel);
flipflop = !flipflop;
panel.Controls.Add(subPanel);
renderSubPanels();
}
void renderSubPanels()
{
panel.SuspendLayout();
bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
foreach (Panel p in listOfPanels)
{
if (verticalScrollVisible)
{
p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
}
else
{
p.Width = panel.Width - 2;
}
p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
}
panel.ResumeLayout();
}
在我的真实程序中,它实际上是一个我正在使用的自定义面板,因此我对创意持开放态度。我只想让讨厌的东西消失!
谢谢!
答案 0 :(得分:2)
注释掉AutoScroll:
//panel.AutoScroll = true;
然后添加此代码:
panel.ControlAdded += panel_ControlAdded;
void panel_ControlAdded(object sender, ControlEventArgs e) {
panel.AutoScrollMinSize = new Size(0,
panel.Controls.Cast<Control>().Sum(x => x.Height));
}
FlowLayoutPanel可能会为你做这件事。
您当前的代码执行了太多不必要的工作。您不需要renderSubPanels()
方法,因此您可以对其进行注释,并且当滚动位置不在原位时,您对Top位置的定位不起作用。只需设置子面板的Anchor属性,它就会正确地说明VerticalScrollBar是否可见:
Panel subPanel = new Panel() {
Height = 100,
BackColor = flipflop ? Color.PeachPuff : Color.PowderBlue,
// updated properties:
Top = panel.Controls.Cast<Control>().Sum(x => x.Height) + panel.AutoScrollPosition.Y,
Width = panel.ClientSize.Width,
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right
};
答案 1 :(得分:1)
我认为您可以使用panel.PerformLayout
代替SuspendLayout
/ ResumeLayout
来获得所需的行为:
void renderSubPanels()
{
//panel.SuspendLayout();
bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
foreach (Panel p in listOfPanels)
{
if (verticalScrollVisible)
{
p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
}
else
{
p.Width = panel.Width - 2;
}
p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
}
//panel.ResumeLayout();
panel.PerformLayout();
}
这似乎对我有用。