滚动条只出现在第一个元素上

Scrollbar only appears for the first element

我有一个非常简单的 windows 表格。从下面的图片中可以看出,滚动条只出现在第一个项目上,但是一旦我通过拖动它的边框使表单变大,滚动条就会消失。这背后的原因是什么?

表单代码如下所示:

var tlp1 = new TableLayoutPanel();
tlp1.Dock = DockStyle.Top;
tlp1.AutoSize = true;
tlp1.BackColor = Color.Bisque;

var tlp2 = new TableLayoutPanel();
tlp2.Dock = DockStyle.Fill;
tlp2.BackColor = Color.DarkSeaGreen;

page.Controls.Add(tlp2);
page.Controls.Add(tlp1);

for (var i = 0; i < 10; i++)
{
    tlp1.Controls.Add(new TextBox()
    {
        Text = string.Format("page1. {0}", i)
    });

    tlp2.Controls.Add(new TextBox()
    {
        Text = string.Format("page2. {0}", i)
    });
}

page.AutoScroll = true;

可滚动区域将是 LayoutEngine 排列后添加到 ScollableContainer 的所有控件的最大值(x + 宽度,y + 高度)。

因为 tlp2.Dock = DockStyle.Fill,它的 ClientRectangle (x, y, width, height) 是任何 space 可用的。换句话说,由于米色面板占据了所有可用高度,因此绿色面板客户端高度 (ClientRectangle.Height) 为零。当您增加主要 window 的高度时,更多 space 可用,额外的高度将分配给绿色面板。但是,当设置为 DockStyle.Fill 时,绿色面板不会满足 space 的需求。

如果设置如下:

tlp2.Dock = DockStyle.Bottom;
tlp2.AutoSize = true;

然后您将拥有一个横跨两个面板整个高度的滚动条。或者另一种方法是将面板添加到垂直 FlowLayoutPanel,例如

class FormTab : Form {

    public FormTab() {
        TabControl tc = new TabControl { Dock = DockStyle.Fill };
        TabPage page = new TabPage();
        var tlp1 = new TableLayoutPanel();
        tlp1.Dock = DockStyle.Top;
        tlp1.AutoSize = true;
        tlp1.BackColor = Color.Bisque;

        var tlp2 = new TableLayoutPanel();
        tlp2.Dock = DockStyle.Bottom;
        tlp2.AutoSize = true;
        tlp2.BackColor = Color.DarkSeaGreen;

        VFLP p = new VFLP();
        p.SuspendLayout();
        p.Controls.Add(tlp2);
        p.Controls.Add(tlp1);
        page.Controls.Add(p);
        //page.Controls.Add(tlp2);
        //page.Controls.Add(tlp1);

        for (var i = 0; i < 10; i++) {
            tlp1.Controls.Add(new TextBox() {
                Text = string.Format("page1. {0}", i)
            });

            tlp2.Controls.Add(new TextBox() {
                Text = string.Format("page2. {0}", i)
            });
        }

        this.DoubleClick += delegate {
            Size s = page.GetPreferredSize(Size.Empty);
            int bp = 1;
        };

        tc.TabPages.Add(page);
        page.AutoScroll = true;
        Controls.Add(tc);
        p.ResumeLayout(true);
    }

    class VFLP : FlowLayoutPanel {

        public VFLP() {
            this.BackColor = Color.AliceBlue;
            WrapContents = false;
            FlowDirection = FlowDirection.TopDown;
            AutoSize = true;
            AutoSizeMode = AutoSizeMode.GrowAndShrink;
        }

        public override Size GetPreferredSize(Size proposedSize) {
            Size s = base.GetPreferredSize(proposedSize);
            Size s2 = Size.Empty;
            foreach (Control c in Controls) {
                Size s3 = c.GetPreferredSize(Size.Empty);
                Padding m = c.Margin;
                s2.Height += s3.Height + m.Vertical;
                int w = s3.Width + m.Horizontal;
                if (w > s2.Width)
                    s2.Width = w;
            }

            return s2;
        }
    }
}