3.2 スタックパネル
3.2.1 自動レイアウトによる要素の積み重ね
Canvas クラスによる明示的な座標指定は、これまで Visual Basic や .NET の Windows Forms アプリケーション開発によるコントロールの配置と同じ方法なので、容易に利用してしまいがちですが、Canvas はコントロールの配置に利用することは推奨されていません。通常、Canvas は、絶対的な座標指定で UIElement を固定しなければならない場合に利用します。これは、ゲームやマルチメディア関連のアプリケーション開発で使われるでしょう。
アプリケーションを操作するための一般的なコントロールは Canvas 以外の Panel を継承するオブジェクトに配置するべきです。なぜならば、Canvas 以外の Panel を継承するクラスは、子要素の座標やサイズを自動的に管理し、調整してくれる機能があるためです。
ウィンドウのサイズがユーザーの手によって変更された場合、内部のコントロールのサイズもそれに合わせてサイズを調整するのが一般的なアプリケーションの挙動です。こうした作業は、 親コントロールのサイズが変更される度に、子コントロール全体の数やサイズを調べ、 全体のバランスを考えながら、正しく各要素の座標とサイズを算出しなければなりません。当然、容易ではありません。
そこで、Panel を実装するクラスが、子要素全体を正しくレイアウトするための汎用的なロジックを提供するのです。子要素を管理する機能が Panel クラスで抽象化されている理由はそこにあります。Panel は、任意の数の子要素を保有し、表示することができるコンテナの役割を持ちますが、子要素をどのようにレイアウトするかというロジックの提供は、派生クラスに委ねているのです。
System.Windows.Controls.StackPanel クラスは、自動レイアウトを行ってくれるパネルの中でも、最もシンプルなレイアウトを提供しています。このクラスは、追加されている子要素を、縦方向、または横方向に向かって、単純に並べてくれます。ウィンドウ上部に表示されるメニューや、ツールバーのように、タン方向に向かって並べられるコントロールの配置に利用されるのが一般的です。
System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Panel System.Windows.Controls.StackPanel
public class StackPanel : Panel, IScrollInfo
StackPanel クラスのコンストラクタは、パラメータを何も受け取りません。
public StackPanel ()
後は Canvas クラスと同様に Children プロパティから UIElement オブジェクトを追加するだけです。StackPanel クラスは、Canvas クラスとは異なり、コントロールを自動的にレイアウトしてくれるため、座標を明示的に指定する必要はありません。
using System; using System.Windows; using System.Windows.Controls; class Test { [STAThread] public static void Main() { StackPanel panel = new StackPanel(); string[] texts = { "Melancholy", "Sighs", "Boredom" }; foreach(string text in texts) { Button button = new Button(); button.Content = text; panel.Children.Add(button); } Window wnd = new Window(); wnd.Content = panel; Application app = new Application(); app.Run(wnd); } }
コード1は、StackPanel に Button オブジェクトを 3 つ追加し、それを Window オブジェクトのコンテンツとして表示させています。各ボタンは、パネルに追加した順番に、垂直方向に並べられます。垂直方向に並べられた場合、要素の高さはオブジェクトの設定に従いますが、幅はパネルのサイズに伸縮されます。
コントロールを並べる方向は Orientation プロパティから設定することができます。
public Orientation Orientation { get; set; }
Orientation プロパティには、方向を表す System.Windows.Controls.Orientation 列挙体のいずれかのメンバを設定します。
[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)] public enum Orientation
Orientation 列挙体は、水平方向を表す Horizontal メンバと、垂直方向を表す Vertical メンバが定義されています。StackPanel の Orientation プロパティの既定では Virtical が設定されています。子要素を水平方向に並べるには Horizontal を設定してください。
using System; using System.Windows; using System.Windows.Controls; class Test { [STAThread] public static void Main() { StackPanel panel = new StackPanel(); panel.Orientation = Orientation.Horizontal; string[] texts = { "Vanishing", "Rampage", "Agitation", "Intrigues" }; foreach(string text in texts) { Button button = new Button(); button.Content = text; panel.Children.Add(button); } Window wnd = new Window(); wnd.Content = panel; Application app = new Application(); app.Run(wnd); } }
コード2は、水平方向に子要素を配置する StackPanel の例です。Orientation プロパティに対して Horizontal を指定することで、子要素は追加した順番で、左から右に配置されるようになりました。