はじめに
Anchor プロパティに設定できる値(Top、Bottom、Left、Right)の組み合わせは 16 パターンあります。
Top | Bottom | Left | Right | |
---|---|---|---|---|
1 | ||||
2 | ✓ | |||
3 | ✓ | |||
4 | ✓ | ✓ | ||
5 | ✓ | |||
6 | ✓ | ✓ | ||
7 | ✓ | ✓ | ||
8 | ✓ | ✓ | ✓ | |
9 | ✓ | |||
10 | ✓ | ✓ | ||
11 | ✓ | ✓ | ||
12 | ✓ | ✓ | ✓ | |
13 | ✓ | ✓ | ||
14 | ✓ | ✓ | ✓ | |
15 | ✓ | ✓ | ✓ | |
16 | ✓ | ✓ | ✓ | ✓ |
パターン毎にコントロールの相対位置(Anchor は親コントロールに対して作用するため、親に対する位置が変わる。という意味です)とサイズが変わりますが、考えるべきパターンを見落としたり、パターン毎の動きがぱっと思い浮かばないことがよくあります。そこで、このパターンのすべての挙動をまとめました。
Anchor の挙動
Windows フォーム(Form1
)に置いたボタン(button 1
)に対して Anchor を設定していきます。
このようなサンプルアプリを用意しました。ウィンドウサイズを変更(300 x 200
→ 450 x 400
)した際、Anchor を設定したボタンの「位置とサイズの何が変わったのか?」を分かりやすくするため、変化したプロパティ([X]
[Y]
[W(idth)]
[H(eight)]
)を 赤く 表示します。
1. None
2. Top
3. Bottom
4. Top, Bottom
5. Left
6. Top, Left
7. Bottom, Left
8. Top, Bottom, Left
9. Right
10. Top, Right
11. Bottom, Right
12. Top, Bottom, Right
13. Left, Right
14. Top, Left, Right
15. Bottom, Left, Right
16. Top, Bottom, Left, Right
サンプルアプリのソースコード
サンプルアプリは .NET 8 環境の Windows フォームアプリケーションとして作成しました。
namespace AnchorSample;
public partial class Form1 : Form
{
private const int X = 180;
private const int Y = 110;
private const int W = 90;
private const int H = 40;
public Form1()
{
InitializeComponent();
DoubleClick += (_, _) =>
{
Size = Width == 300
? new Size(450, 400)
: new Size(300, 200);
ShowProperties();
};
ShowProperties();
}
private void ShowProperties()
{
labelA.Text = @"[Anchor] " + button1.Anchor;
labelX.Text = $@"[X] {button1.Location.X}";
labelY.Text = $@"[Y] {button1.Location.Y}";
labelW.Text = $@"[W] {button1.Size.Width}";
labelH.Text = $@"[H] {button1.Size.Height}";
labelX.ForeColor = button1.Location.X == X
? Color.Black
: Color.Red;
labelY.ForeColor = button1.Location.Y == Y
? Color.Black
: Color.Red;
labelW.ForeColor = button1.Size.Width == W
? Color.Black
: Color.Red;
labelH.ForeColor = button1.Size.Height == H
? Color.Black
: Color.Red;
}
}
Anchor 設定の階層
次に、コントロールに親子関係がある場合の Anchor 設定について考えてみます。
例えば、ウィンドウの下部にフッター領域を作り、ボタンを3つ配置する場合、フッターをウィンドウ下部に固定しようとすると、None
と Top, Left
ではうまくいきません。
Bottom, Left, Right
とすると意図した配置となりました。
次に、ボタンを「均等に並べたい」とします。ボタンの幅を変えずにボタン間の間隔を伸ばす対応であれば、下記のように設定することで実現できます。
しかしながら、ボタンの幅も伸ばしたい!と考え、ボタンの Anchor を Left, Right
に設定すると、下記のようになってしまいます。
Anchor 設定の階層を対象とすると、ボタンのどの部分の余白を伸ばすか?だったり、ボタンの幅をどのようなルールで伸ばすか?だったり、考えなければならないことは意外と多いです。また実装の際も、他のコントロールと組み合わせたり、計算して幅を求めたり、という対応が必要になります。
おわりに
Anchor 設定はすぐに「あれ?」となってしまうので、ことあるごとに見直そうと思います。また、階層構造を対象とする場合は、どのような対応とするか?をよくよく考える必要があります。