表格布局面板显示垂直滚动条

18

我有一个TableLayoutPanel用于动态创建控件,其中AutoScroll=true。当我添加新的控件时,它可以正常工作。但是,当我删除所有控件并且所有控件都可见时,垂直滚动条会出现。

这里有一些屏幕截图:

期望/正确的滚动条可见性:

enter image description here

错误的可见性:

enter image description here

有什么想法吗?

更新:这是一些代码

tableLayoutPanel1.SuspendLayout();
tableLayoutPanel1.RowCount = 0;
tableLayoutPanel1.RowStyles.Clear();
tableLayoutPanel1.AutoScroll = true;
tableLayoutPanel1.Padding = new Padding(0, 0, SystemInformation.VerticalScrollBarWidth, 0);
foreach (var item in objects)
{
     tableLayoutPanel1.RowCount++;
     tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
     tableLayoutPanel1.Controls.Add(CreateNewItem(item));
 }

 tableLayoutPanel1.RowCount++;
 tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
 tableLayoutPanel1.Controls.Add(CreateAddButton());

 tableLayoutPanel1.ResumeLayout();

以及删除代码

tableLayoutPanel1.SuspendLayout();
tableLayoutPanel1.Controls.Remove(item);
tableLayoutPanel1.RowStyles.RemoveAt(0);
tableLayoutPanel1.RowCount--;
tableLayoutPanel1.ResumeLayout();

AutoSize为真,AutoSizeMode为GrowAndShrink


当您移除控件时,您是否也同时移除了行? - LarsTech
@LarsTech 是的。最后一行是AutoSize样式,但看起来像百分比。 - Maksym
1
.Net Framework 4.8 这个 bug 仍然存在。 - 23W
6个回答

64
该问题涉及到关于 TableLayoutPanel 滚动 的问题。
您需要使用一个 Panel 进行滚动而非 TableLayoutPanel。
以下是解决此问题的示例(用于垂直滚动):
  • 将 TableLayoutPanel 属性设置如下:
    • Dock = DockStyle.Top
    • AutoSize = true
    • AutoSizeMode = AutoSizeMode.GrowAndShrink
    • AutoScroll = false。
  • 将 TableLayoutPanel 放入一个带有以下属性的 Panel 中:
    • Dock = DockStyle.Fill
    • AutoScroll = true
    • AutoSize = false。

1
7年过去了,这仍然是一个可行的解决方案。但为什么在TableLayoutPanel上设置DockStyle.Top是必需的(而不是Fill)?没有它,经验证明它不起作用 - 但我不理解其逻辑。 - user1169420
2
如果您设置DockStyle.Fill,TableLayoutPanel将具有与其父级相同的尺寸,因此面板将永远不会显示滚动条。 - Bioukh
1
这就是为什么我会这样做。在需要的时候,这是一个金色的答案。 - Ted W

2
当您移除动态控件时,需要移除添加期间插入的额外行,并将表格布局面板的高度调整为小于滚动容器的高度。
在添加期间,表格布局面板的高度会增加,这由滚动容器处理; 但是当您移除控件时,表格布局面板的高度不会减小以适应滚动容器。
一种方法是给行固定高度,并将表格布局面板大小设置为“自动”。

每行都有AutoSize样式,而且tableLayoutPanel.AutoSize为true。 - Maksym

1

最简单有趣的解决方案之一是禁用并启用 tableLayoutPanel1.AutoScroll

在您的删除过程代码中最后添加以下代码:

    tableLayoutPanel1.AutoScroll = False
    tableLayoutPanel1.AutoScroll = True

0
我数了一下我的TableLayoutPanel中的行数,以确定可以容纳多少行。在适量的行数以下,我为添加和删除方法设置了AutoScroll = false。对于大型数据集,滚动条将出现,而对于小型数据集,滚动条将消失。
if (tableLayoutPanel.RowCount < 15)
{
    panel1.AutoScroll = false;
}
else
{
     panel1.AutoScroll = true;
}

0
我在XtraScrollableControl(Devexpress控件)中插入了tableLayoutPanel。 tableLayoutPanel.Dock设置为Top,而XtraScrollableControl.Dock设置为Fill。这个解决方案没有解决这个问题,但我得到了我需要的行为。

-1

我在一个UserControl上放了一个TableLayoutPanel,以填充模式固定,所有行都设置为AutoSize。然后,这个UserControl会动态地放在一个面板上,再次被填充模式使用,以便在需要时向用户展示。我把UserControl放在AutoScroll上,但仅靠这一点还不足以解决问题。

最终,我通过遍历TableLayoutPanel中的所有控件,存储极端值,并将其烘制成一个Size放入我的UserControlAutoScrollMinSize中来解决了它:

private void AdjustPanelSize(ScrollableControl panel, TableLayoutPanel tableLayoutPanel)
{
    int maxX = 0;
    int maxY = 0;
    foreach (Control c in tableLayoutPanel.Controls)
    {
        maxX = Math.Max(maxX, c.Location.X + c.Width);
        maxY = Math.Max(maxY, c.Location.Y + c.Height);
    }
    panel.AutoScrollMinSize = new Size(maxX, maxY);
}

这个方法可行,而且它还有一个优点,就是如果从TableLayoutPanel中动态添加或删除控件,它也可以被调用。


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