为什么设置MinimumSize会破坏表格布局?

时间:2014-12-31 07:19:10

标签: c# winforms layout

我目前正在玩布局并制作了一个测试项目,我在其中构建一个Form,其中显示一个Panel,其中包含一个包含三行的TableLayoutPanel:

  • 一个文本框
  • 一个按钮
  • 占位符标签,应该占用剩余的垂直空间。

此测试正常,但如果我将文本框的最小尺寸设置为例如(400,200),我再也看不到按钮了。表格布局AutoSize中的第一行不应该是其内容吗?注意 将RowStyles明确设置为SizeType.AutoSize并不会改变任何内容。


未设置最小尺寸:

Screenshot where the text box and button are visible

最小尺寸设定:

Screenshot where the button is hidden behind the text box


using System;
using System.Drawing;
using System.Windows.Forms;

namespace LayoutTest
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            var sampleForm = new Form();
            var samplePanel = new Panel() { Dock = DockStyle.Fill };
            var sampleTextBox = new TextBox() { Dock = DockStyle.Fill };
            // This line breaks the layout
            //sampleTextBox.MinimumSize = new Size(400, 200);
            var sampleButton = new Button() { Dock = DockStyle.Fill };

            var panelLayout = new TableLayoutPanel() { Dock = DockStyle.Fill };
            panelLayout.Controls.Add(sampleTextBox, 0, 0);
            panelLayout.Controls.Add(sampleButton, 0, 1);
            // Add a placeholder label to take up the remaining space
            panelLayout.Controls.Add(new Label() { Text = String.Empty, Dock = DockStyle.Fill });

            samplePanel.Controls.Add(panelLayout);

            sampleForm.Controls.Add(samplePanel);

            Application.Run(sampleForm);
        }
    }
}

1 个答案:

答案 0 :(得分:4)

按钮位于文本框下方。您需要将multiline属性设置为true

E.g。

sampleTextBox.Multiline = true;

此行为的来源是TableLayoutPanelTextBoxTableLayoutPanel明确测试Control是否为TextBox并且Multiline属性设置为true,然后才决定遵守MinimumSize约束。但是,在我的测试中,似乎必须先设置Multiline属性,然后才将其添加到TableLayoutPanel,如果Multiline未设置,则控件会返回到文本框下方,从不即使Multiline再次设置为true,也会返回。

E.g。

        sampleButton.Click += delegate {
            Size s1 = sampleTextBox.MinimumSize; // always returns the set MinSize
            sampleTextBox.Multiline = !sampleTextBox.Multiline;
            Size s2 = sampleTextBox.MinimumSize; // always returns the set MinSize
            panelLayout.Invalidate(true);
            panelLayout.PerformLayout();
        };