Visual Basic 初級講座
VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

 

Visual Basic 中学校 > 初級講座 >

第18回 コントロールの配置

フォームの大きさを変えたときにもレイアウトが乱れない自動配置や、マウスを使ってコントロールの境界線を自由にずらす方法など。コントロールの配置に関する話題を説明します。

この回の要約

・Anchorプロパティを使うとフォームの大きさが変わってもコントロールは自動的に再配置される。

・Dockプロパティを使うとフォームの大きさが変わってもコントロールはフォーム上の決まった領域に配置される。

・DockプロパティとSplitterを組み合わせてユーザーがマウスで境界線を自由に変更できるようにできる。

・SplitContainerを使ってユーザーがマウスで境界線を自由に変更できるようにできる。

・Resizeイベントを使ってコントロールの再配置を細かく制御することができる。

 

1.前置き

 

コントロールはデザイン時にマウスで好きなところに配置することができます。このときVB2005以上ではコントロールの位置を他のコントロールとそろえるためのガイドラインが表示されますし、プロパティウィンドウでLeftプロパティやTopプロパティに細かい数字を指定して位置を微調整することもできます。

こういうわけですから一見コントロールの配置はスムーズに行くように思えますが実はそうとも限りません。

今回はコントロールの自動配置を中心としたトピックを扱います。

 

2.ユーザーはマウスでフォームの大きさを変更するでしょう

 

Windowsである限りユーザーはマウスを使って自由にフォームの大きさを変更することができます。あなたの作ったアプリケーションは大きさが変更されるとどうなるでしょうか?

たとえば、フォームの右下に[OK]ボタンを配置したとします。そしてユーザーがマウスでフォームを大きくしました。あなたの[OK]ボタンはどうなるでしょうか?対策をとっていなければ[OK]ボタンには何も起こりません。その結果フォームは間延びした間抜けなレイアウトになってしまいます。

■画像1:フォームの左の画面からフォームの大きさを変えると右の画面のような間抜けなレイアウトになる。

また、ユーザーがどうしてフォームの大きさを変更するのか考えてみてください。フォームを小さくする場合はそのフォームが邪魔だからでしょう。この場合はユーザーはそのフォームには特に何も期待していないことがほとんどなのでここでは あまり問題になりません。

逆にフォームを大きくする場合ユーザーは「大きさ」を望んでいるのです。たとえば、フォームに表示されている一覧が小さいのでフォームを大きくしていっぺんにもっとたくさんの一覧が表示されるようにしたいとか、表示されている文章が少ないのでいっぺんにもっとたくさん表示できるようにしたいとか、ゲームやマルチメディアならもっと大きく表示したいとか、そういうことを考えてユーザーはフォームを大きくします。

なのに対策を取っていないフォームではフォームが大きくなっても中身は大きくなりません。これではユーザーはがっかりしてそのソフトが嫌いになり、最後には同じ機能がある別のソフトを探し始めるでしょう。

このことに対する最も簡単な対策は、フォームの大きさを変えられないようにすることです。フォームの大きさを変えられないようにするにはフォームのFormBorderStyleプロパティ (読み方:FormBorderStyle = フォームボーダースタイル)をFixedDialog(読み方:FixedDialog = フィックスドダイアログ)などに変更します。これだけです。 ただし、ユーザーの要求から考えるとこれは抜本的対策ではないことがほとんどです。

さて、より効果的な対策もあります。VBでは幸いなことにちょっとしたプロパティを設定しておくだけで、フォームの大きさが変わっても自動的に中身のコントロールを自動配置してくれる機能があります。

それが、Dockプロパティ(読み方Dock = ドック)と、Anchorプロパティ(読み方:Anchor = アンカー)プロパティです。

 

3.Anchorプロパティ

 

Anchorプロパティはフォームの端とコントロールの位置を自動的に結びつけるプロパティです。

たとえば、AnchorプロパティをRight(読み方:Right = ライト)にしておくと、フォームの大きさが変わってもフォームの右端から、コントロールの右端までの距離が変わらないように自動的にコントロールを移動してくれます。

プロパティウィンドウではAnchorプロパティはちょっと変わった方法で設定します。直感的で分かりやすい方法だと思います。

■画像2:プロパティウィンドウでのAnchorの設定

実際にボタンのAnchorRightにしたときの動作を参考に画像 で掲載しておきますが、やはり説明するより実際にやってみた方がよく分かると思いますので是非試してみてください。

■画像3:Anchorプロパティ = Rightなのでフォームの大きさを変更してもボタンの右端からフォームの右端までの距離が変わらない。

Anchorプロパティの既定値はTop, Leftです。つまり、上端と左端の距離を保つようになっています。たしかに何も設定しなければフォームの大きさを変えても、コントロールとフォームの上端の距離と左端の距離はかわりません。また、このようにAnchorプロパティにはTop, Bottom, Left, Rightの4つを自由に組み合わせて設定できることも重要です。各設定の意味を表にまとめておきます。

設定値 読み方 意味
Top トップ フォームの上端とコントロールの上端の距離を一定に保つ。
Bottom ボトム フォームの下端とコントロールの下端の距離を一定に保つ。
Left レフト フォームの左端とコントロールの左端の距離を一定に保つ。
Right ライト フォームの右端とコントロールの右端の距離を一定に保つ。

さて、Anchorプロパティを使ってコントロールの大きさを変更することもできます。たとえば、次のようなフォームがあったとします。(このフォームではテキストボックスのMultiLineプロパティがTrueになっていることに注意してください。MultiLineプロパティがFalseのままではテキストボックスをこのように大きく配置することはできません。)

■画像4

このフォームの大きさをいろいろと変更してもコントロールの配置が乱れないようにするにはどのようにAnchorプロパティを設定すべきでしょうか?どこの距離を一定に保つべきか考えてみてください。

Anchorプロパティを適切に設定すれば何もプログラムしないでもユーザーの期待通りにコントロールを再配置することができます。

■画像5:Anchorプロパティを適切に設定するだけでフォームの大きさを変えてもレイアウトが保たれるようになる。

この動作を実現するには、テキストボックスのAnchorプロパティを「Top, Bottom, Left, Right」に、ボタンのAnchorプロパティを「Bottom, Right」に設定します。

この設定ではAnchorプロパティで定められた距離を一定に保つためにテキストボックスは変形することになります。

 

4.Dockプロパティ

 

DockプロパティはAnchorプロパティとは別の方法でコントロールを自動配置します。Dockプロパティにはコントロールがフォーム上でどの位置を占めるのかを設定します。

たとえば、フォームにテキストボックスを1つだけ配置してDockプロパティをFill(読み方:Fill = フィル)に設定すると、テキストボックスはフォームがどのような大きさになろうとも常にフォーム全体に広がります。なお、当然そのテキストボックスのMultiLineプロパティはTrueになっていなければなりません。

Dockプロパティも独特の設定画面を使って設定します。

■画像6:プロパティウィンドウでのDockプロパティの設定

この画面でNone(読み方:None = ノン)を選択するとDockプロパティは何も選択されていない既定値に戻ります。中央のボタンはFillを表し、四囲のボタンはやはりTop, Bottom, Left, Rightを表しています。

Dockプロパティをもっとうまく使う例を紹介しましょう。2つのコントロールにDockプロパティを設定してうまく自動配置させます。

ここでは画面で分かりやすいように2つのラベルを使いますがラベルである必要はありません。2つのラベルには1つ目は青、2つ目は赤の色をつけて見た目でわかるようにしています。

■画像6

まず、青いラベルを画像のような大きさで配置してDockプロパティをLeftにしてください。次に赤いラベルを適当に配置してDockプロパティをFillにしてください。これだけで自動配置可能な2つのラベルができたことになります。実行してフォームの大きさをいろいろと変えてみてください。

さて、こうなると青いラベルと赤いラベルの境界線をユーザーがマウスで変更できたら素敵だとは思いませんか?実はそのための機能も用意されています。

VB2005以降ではこの機能を実現するためにSplitContainerというコントロールが用意されていますのでこの説明を読む必要はありません。SplitContainerについてはすぐ次の節で紹介します。

VB.NET2002, VB.NET2003をお使いの場合には以下の手順を実際にやってみることをお勧めします。

まず、いったん赤いラベルを削除してください。そして、Splitterを適当に張りつけてください。この状態でSplitterを貼り付けると自動的に青いラベルの右側にくっつきますので幅を狭くして「線」に見えるようにしてください。

■画像7:Splitterのアイコン

そして再び赤いラベルを配置してDockプロパティをFillにします。

実行してみるとどうでしょうか。マウスで自由に青いラベルと赤いラベルの境界をずらすことができます。

■画像8:マウスで境界線を自由に移動できる

これはまったくすばらしいことです。VB6の時代にはこの機能を実現するためにこちょこちょと小細工する必要がありましたが今ではプロパティをちょこちょこと設定するだけでできるようになりました。

なお、SplitterDockプロパティをTopにすることで、横方向ではなく縦方向に境界を移動できるように構成することもできます。

また、パネルの中にSplitterを配置することもできるので複数のパネルとSplitterを組み合わせてさらに複雑な動きをさせることも可能です。

 

5.SplitContainer

 

この節の説明はVB2005以降でのみ使用可能なコントロールSplitContainer(読み方:SplitContainer = スプリットコンテナ)に関するものです。

SplitContainerを使うと、驚くほど簡単にユーザーがマウスで自由に境界を移動できる領域を作ることができます。

以下の手順でコントロールを配置して、実際に簡単さとその効果を感じてみてください。

1.SplitContainerをフォームに適当に貼り付けます。

貼り付けるとSplitContainerは自動的にフォームいっぱいに広がります。つまりDock = Fill の状態になります。

2.SplitContainerの左側の領域に適当にラベルを貼り付けてください。

貼り付けたラベルのプロパティは次の通り設定してください。

プロパティ 説明
AutoSize False テキストに合わせて幅を自動調節しないようにします。
BackColor (青い色) 目立たせます。
Dock Fill 左側の領域全体に広がるようにします。

3.SplitContainerの右側の領域に適当にラベルを貼り付けてください。

貼り付けたラベルのプロパティは次の通り設定してください。

プロパティ 説明
AutoSize False テキストに合わせて幅を自動調節しないようにします。
BackColor (赤い色) 目立たせます。
Dock Fill 左側の領域全体に広がるようにします。

文章で説明すると意外と長くなってしまったのが残念ですが作業はこれだけです。実行してみるとマウスで青い部分と赤い部分の境界を移動できるのがわかります。快適ですね。

なお、SplitContainerOrientationプロパティ(読み方:Orientation = オリエンテーション)をHorizontal(読み方:Horizontal = ホリゾンタル)にすることで、横方向ではなく縦方向に境界が移動できるようにする構成も可能です。

また、SplitContanerの中にSplitConatnerを配置するなどしてさらに複雑な動きをさせることもできます。

 

6.手動での再配置

 

最後に手動での再配置を説明しましょう。今回は「自動的に」再配置することを中心に説明してきましたが自分でプログラムして細かく制御することももちろん可能です。

フォームの大きさが変更したときはResizeイベント(読み方:Resize = リサイズ)が発生するのでそのタイミングで自分で各コントロールの座標を指定します。

たとえば次の例は常にButton1がフォームの右下に表示されるようにします。

VB.NET2002対応 VB.NET2003対応 VB2005対応

Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize

    Button1.Left = Me.ClientSize.Width - Button1.Width - 10
    Button1.Top =
Me.ClientSize.Height - Button1.Height - 10

End Sub

この例と同じことをするのであればAnchorプロパティを使った方が簡単です。通常Resizeイベントによる再配置は自動化できないような複雑な配置の場合に行います。