【C#】【Windowsフォームアプリケーション】SplitContainerとFlowLayoutPanelを使ってGUIを構築するぞ

はじめに

なるべくコントロール(ボタンやテキストボックスなど)のサイズや位置を指定しない方法を考えます。

各論

SplitContainerのSplitterDistanceを固定する


青い領域の高さを100に指定しています。


その領域内で上下中央にコントロール(ボタンやテキストボックス)を配置する方法です。


配置するコントロールはAnchor:Noneを指定すると真ん中に配置されます。


ただし基準となるものが必要となるのでダミーボタンを一つ配置しました。


これ以外の方法が思いつきませんでした。


GUI構築のコードはForm1_Loadとして記述しないとうまく動作しませんでした(原因不明)。

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

namespace WindowsFormsApp5
{
    public partial class Form1 : Form
    {
        SplitContainer sp1 = new SplitContainer();
        FlowLayoutPanel flp1 = new FlowLayoutPanel();

        Button dummy = new Button();

        TextBox txt1 = new TextBox();
        Button btn1 = new Button();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, System.EventArgs e)
        {
            sp1.Dock = DockStyle.Fill;
            sp1.Orientation = Orientation.Horizontal;
            sp1.FixedPanel = FixedPanel.Panel1;
            sp1.IsSplitterFixed = true;
            sp1.BackColor = Color.Blue;
            sp1.Panel2.BackColor = Color.Red;
            Controls.Add(sp1);

            flp1.Dock = DockStyle.Fill;
            flp1.FlowDirection = FlowDirection.LeftToRight;
            sp1.Panel1.Controls.Add(flp1);
            sp1.SplitterDistance = 100;
            dummy.Size = new Size(0, sp1.Panel1.Height);
            dummy.Margin = new Padding(0, 0, 0, 0);

            txt1.Anchor = AnchorStyles.None;

            btn1.Text = "Push";
            btn1.Anchor = AnchorStyles.None;

            flp1.Controls.Add(dummy);
            flp1.Controls.Add(txt1);
            flp1.Controls.Add(btn1);
        }
    }
}

テキストボックスのフォントのみを指定する


SplitterDistanceを直接数値で指定していません。


SplitterDistanceはテキストボックスの高さ+10になるようにしています。

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

namespace WindowsFormsApp6
{
    public partial class Form1 : Form
    {
        SplitContainer sp1 = new SplitContainer();
        FlowLayoutPanel flp1 = new FlowLayoutPanel();

        Button dummy = new Button();

        TextBox txt1 = new TextBox();
        Button btn1 = new Button();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            sp1.Dock = DockStyle.Fill;
            sp1.Orientation = Orientation.Horizontal;
            sp1.FixedPanel = FixedPanel.Panel1;
            sp1.IsSplitterFixed = true;
            sp1.Panel1.BackColor = Color.Blue;
            sp1.Panel2.BackColor = Color.Red;

            Controls.Add(sp1);

            flp1.FlowDirection = FlowDirection.LeftToRight;
            flp1.Dock = DockStyle.Fill;

            sp1.Panel1.Controls.Add(flp1);

            txt1.Font = new Font("游ゴシック", 11);
            txt1.Anchor = AnchorStyles.None;
            
            btn1.Text = "push";
            btn1.Height = txt1.Height;
            btn1.Anchor = AnchorStyles.None;

            sp1.SplitterDistance = txt1.Height + 10;
            dummy.Size = new Size(0, sp1.Panel1.Height);
            dummy.Margin = new Padding(0, 0, 0, 0);
            flp1.Controls.Add(dummy);
            flp1.Controls.Add(txt1);
            flp1.Controls.Add(btn1);
        }
    }
}

ラベルとテキストボックスのセットを縦に並べる

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

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        SplitContainer sp1 = new SplitContainer();
        FlowLayoutPanel flp1 = new FlowLayoutPanel();

        Label[] labels = new Label[3];
        String[] labels_text = { "しんちょう", "たいじゅう", "ふくい" };
        TextBox[] txts = new TextBox[3];

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sp1.Dock = DockStyle.Fill;
            sp1.Orientation = Orientation.Vertical;
            sp1.FixedPanel = FixedPanel.Panel1;
            sp1.IsSplitterFixed = true;

            sp1.Panel2.BackColor = Color.Red;

            Controls.Add(sp1);

            flp1.FlowDirection = FlowDirection.LeftToRight;
            flp1.Dock = DockStyle.Fill;

            sp1.Panel1.Controls.Add(flp1);

            for(int i = 0; i < 3; i++)
            {
                labels[i] = new Label();
                txts[i] = new TextBox();

                txts[i].Font = new Font("游ゴシック", 12);

                labels[i].Text = labels_text[i];
                labels[i].Size = new Size(100, txts[i].Height);
                labels[i].TextAlign = ContentAlignment.MiddleCenter;
                labels[i].Font = new Font("游ゴシック", 12);

                flp1.Controls.Add(labels[i]);
                flp1.Controls.Add(txts[i]);
            }
            sp1.SplitterDistance = labels[0].Width + txts[0].Width + 12;
        }
    }
}

最終行の12はコントロールのマージン(デフォルトは3)×4で算出しています。

ラベルとテキストボックスのセットを横に並べる

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

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        SplitContainer sp1 = new SplitContainer();
        FlowLayoutPanel flp1 = new FlowLayoutPanel();

        Label[] labels = new Label[3];
        String[] labels_text = { "しんちょう", "たいじゅう", "ふくい" };
        TextBox[] txts = new TextBox[3];

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            sp1.Dock = DockStyle.Fill;
            sp1.Orientation = Orientation.Horizontal;
            sp1.FixedPanel = FixedPanel.Panel1;
            sp1.IsSplitterFixed = true;
            sp1.Panel2.BackColor = Color.Red;

            Controls.Add(sp1);

            flp1.Dock = DockStyle.Fill;
            flp1.FlowDirection = FlowDirection.TopDown;

            sp1.Panel1.Controls.Add(flp1);

            for(int i= 0; i < 3; i++)
            {
                labels[i] = new Label();
                txts[i] = new TextBox();

                txts[i].Font = new Font("游ゴシック", 12);

                labels[i].Font = new Font("游ゴシック", 12);
                labels[i].Text = labels_text[i];
                labels[i].Size = txts[i].Size;
                labels[i].TextAlign = ContentAlignment.MiddleCenter;

                flp1.Controls.Add(labels[i]);
                flp1.Controls.Add(txts[i]);
            }
            sp1.SplitterDistance = labels[0].Height + txts[0].Height + 12;
        }
    }
}

最終行の12はコントロールのマージン(デフォルトは3)×4で算出しています。

参考にさせて頂いたサイト

qiita.com

環境

Windows 11
Visual Studio Community 2022

さいごに

もっといい方法があればコメントで教えて頂けたらうれしいです。