WisdomSoft - for your serial experiences.

コントロールの自動レイアウト

座標やサイズで固定するのではなく、ウィンドウなどの親コントロールのサイズに合わせて自動的にレイアウトされるコントロールの設定方法を紹介します。

アンカー

一般的なフォームは、フォームの境界線をドラッグすることで実行時にユーザーが自由にサイズを変更できます。そして、多くの UI デザインでは親コントロールのサイズが変更されれば子コントロールの位置やサイズも調整する必要があるでしょう。

サイズの変更を感知して、プログラムによってコントロールのサイズを再調整することもできますが、この方法は効率的ではありません。Windows フォームでは、コントロールのレイアウトを自動で調整してくれる機能を提供しています。

親コントロールのサイズ変更に対して、子コントロールの位置やサイズを調整するには Anchor プロパティを利用します。これは、親コントロールの端を子コントロールと関連付け、子コントロールの位置を親コントロールに対して相対的に保ちます。

Control クラス Anchor プロパティ
public virtual AnchorStyles Anchor { get; set; }

このプロパティは System.Windows.Forms.AnchorStyles 列挙体の値で、コンテナとなる親コントロールの、どの端と固定するかをビットフラグで表します。

System.Windows.Forms.AnchorStyles 列挙体
[FlagsAttribute]
public enum AnchorStyles
AnchorStyles 列挙体のメンバ
メンバ 説明
Bottom コントロールは、親コントロールの下端に固定されます。
Left コントロールは、親コントロールの左端に固定されます。
None コントロールは固定されません。
Right コントロールは、親コントロールの右端に固定されます。
Top コントロールは、親コントロールの上端に固定されます。

既定でコントロールは親コントロールのサイズ変更の影響を受けず、位置とサイズは固定されています。これは、Anchor プロパティの既定値が AnchorStyles.Left | AnchorStyles.Top だからです。コントロールが常にコンテナの左隅と上隅に対して固定されているためです。

逆に右隅と下隅に固定した場合、コンテナのサイズを変更するとコントロールの位置がサイズの変更に合わせて追従します。ダイアログボックスの確認ボタンなどを表現する時に便利でしょう。

コード1
using System.Windows.Forms;
using System.Drawing;

class Test
{
	public static void Main(string[] args)
	{
		Control control = new Control();
		control.Bounds = new Rectangle(150, 200, 100, 50);
		control.BackColor = Color.Red;
		control.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;

		Form form = new Form();
		form.Controls.Add(control);

		Application.Run(form);
	}
}
実行結果
コード1 実行結果1  コード1 実行結果2

上のプログラムは追加したコントロール(赤い長方形)が常にフォームの右下に固定されています。そのため、サイズを変更してもフォームの右下から一定の余白をとった位置にコントロールが固定されます。

ドック

ステータスバーやメニューバーのようなコントロールを想像して下さい。常にコンテナの端に配置されるようなこのようなコントロールの座標の計算も、Control クラスの機能であるドックによって解決できます。

ドックはコンテナの上下左右の指定した境界にコントロールを貼り合わせ、親コントロールのサイズの変更に合わせて自動的にドッキングされている子コントロールのサイズを調整してくれます。

コントロールをコンテナの境界にドッキングするには Dock プロパティを使います。

Control クラス Dock プロパティ
public virtual DockStyle Dock { get; set; }

このプロパティはコンテナのどの境界にドッキングするのかを表す System.Windows.Forms.DockStyle 列挙体のメンバを指定します。既定ではドッキングしないことを表す None メンバが設定されています。

System.Windows.Forms.DockStyle 列挙体
public enum DockStyle
DockStyle 列挙体のメンバ
メンバ 説明
Bottom コントロールは、親コントロールの下端にドッキングされます。
Fill コントロールは、親コントロールの四辺にドッキングされます。
Left コントロールは、親コントロールの左端にドッキングされます。
None コントロールは、ドッキングされません。
Right コントロールは、親コントロールの右端にドッキングされます。
Top コントロールは、親コントロールの上端にドッキングされます。

DockStyle 列挙型は AnchorStyles 列挙体に似ていますがビット演算は行えません。そのため、アンカーのように複数の境界線に関連付けることはできません。

ドッキングしたコントロールは、関連付けられた親コントロールの境界線と隣接する辺に接触する位置とサイズが自動的に計算されます。この場合、座標やサイズを指定しても無視されます。例えば DockStyle.Top や DockStyle.Bottom を指定したコントロールは高さのみ有効となります。

コード2
using System.Windows.Forms;
using System.Drawing;

class Test
{
	public static void Main(string[] args)
	{
		Control kyouko = new Control();
		kyouko.Height = 50;
		kyouko.BackColor = Color.Red;
		kyouko.Dock = DockStyle.Top;

		Control sayaka = new Control();
		sayaka.Height = 50;
		sayaka.BackColor = Color.Blue;
		sayaka.Dock = DockStyle.Bottom;

		Control madoka = new Control();
		madoka.Width = 50;
		madoka.BackColor = Color.Pink;
		madoka.Dock = DockStyle.Left;

		Control homu = new Control();
		homu.Width = 50;
		homu.BackColor = Color.Black;
		homu.Dock = DockStyle.Right;

		Control mamisan = new Control();
		mamisan.BackColor = Color.Yellow;
		mamisan.Dock = DockStyle.Fill;

		Form form = new Form();
		form.Controls.Add(kyouko);
		form.Controls.Add(sayaka);
		form.Controls.Add(madoka);
		form.Controls.Add(homu);
		form.Controls.Add(mamisan);

		Application.Run(form);
	}
}
実行結果
コード2 実行結果

コード2は上下左右の境界に単色で背景を塗りつぶしたコントロールを配置しています。ウィンドウのサイズを変更しても、正しくコントロールのサイズが調整されます。このような、いわゆるドック型のレイアウトは多くのアプリケーションで共通する基本的なデザインです。

近年の PC 用ディスプレイは高解像度化が進んでいるため、広い画面を生かせる UI をデザインしなければなりません。そのためには、ウィンドウのサイズに従って正しくコントロールのサイズを調整し、より多くの情報を画面に表示できるようにする必要があります。上記したアンカーやドックキングを用いて、柔軟なコントロールの配置が可能となります。