かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その14 「レイアウトコントロールのCanvasとStackPanel」

Canvasコントロール

Canvasコントロールは、子要素をCanvasの中に絶対座標指定で配置できることロールです。これまで紹介してきたBorderコントロールやBulletDecoratorコントロールとは異なり、Canvasコントロールは、配下に子要素を複数持つことができます。


Canvasコントロールで使用するプロパティは以下のようなものがあります。

プロパティ 説明
Bottom添付プロパティ Canvasの下を起点として位置を指定します。
Left添付プロパティ Canvasの左を起点として位置を指定します。
Right添付プロパティ Canvasの右を起点として位置を指定します。
Top添付プロパティ Canvasの上を起点として位置を指定します。

上記の添付プロパティでTopとBottom、LeftとRightが両方設定された場合はTopとLeftが優先されます。Canvasコントロールの使用例を以下に示します。

<Window x:Class="CanvasSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Button Canvas.Top="10" Canvas.Left="10" Content="Button1" />
        <Button Canvas.Top="10" Canvas.Right="10" Content="Button2" />
        <Button Canvas.Bottom="10" Canvas.Left="10" Content="Button3" />
        <Button Canvas.Bottom="10" Canvas.Right="10" Content="Button4" />
    </Canvas>
</Window>

TopとLeftとRightとBottomは添付プロパティなので、XAMLで説明したようにクラス名.プロパティ名の形で設定を行います。このように、親要素(この場合Canvas)に対して子要素(この場合Button)が何かしら情報を提供するために使用します。WPFでは、今回の例のようにレイアウト情報で使われることが多いです。


このWindowを表示すると以下のようになります。

StackPanelコントロール

StackPanelコントロールは、子要素を縦方向または横方向に一列に並べるコントロールです。StackPanelの表示領域からあふれたコントロールは表示されません。StackPanelが子コントロールを並べる際に子コントロールに、左端・右端・上端・下端・中央・領域全体に表示するかを委ねます。デフォルトでは、表示可能な領域いっぱいに子コントロールを配置します。


StackPanelで使用するプロパティには以下のようなものがあります。

プロパティ 説明
Orientation Orientation { get; set; } 子要素を縦並びにするか、横並びにするか設定します。横並びのときはHorizontal、縦並びのときはVerticalを設定します。デフォルトはVerticalです。

縦方向にコントロールを表示する場合のXAMLの例は以下のようになります。

<Window x:Class="StackPanelSample01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Button Content="Button" />
        <!-- 左寄せ -->
        <Button Content="Button" HorizontalAlignment="Left" />
        <!-- 右寄せ -->
        <Button Content="Button" HorizontalAlignment="Right" />
        <!-- センタリング -->
        <Button Content="Button" HorizontalAlignment="Center" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
    </StackPanel>
</Window>

一部のボタンではHorizontalAlignmentプロパティで水平方向の配置の仕方を指定しています。このWindowを表示すると以下のようになります。水平方向の表示位置を設定したボタンの表示のされかたに注目してください。

続けてOrientationをHorizontalにして水平方向に子要素を配置する場合のXAMLを以下に示します。

<Window x:Class="StackPanelSample02.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Horizontal">
        <Button Content="Button" />
        <!-- 上寄せ -->
        <Button Content="Button" VerticalAlignment="Top" />
        <!-- 下寄せ -->
        <Button Content="Button" VerticalAlignment="Bottom"/>
        <!-- 中央寄せ -->
        <Button Content="Button" VerticalAlignment="Center"/>
        <Button Content="Button" />
        <!-- ボタンの周囲に余白を作る -->
        <Button Content="Button" Margin="5" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
        <Button Content="Button" />
    </StackPanel>
</Window>

これも一部ボタンで、VerticalAlignmentプロパティを指定して垂直方向の位置の調整をおこなっています。さらにMarginというプロパティを使用して、レイアウト可能な領域に対して上下左右の余白を設定しているボタンもあります。MarginプロパティはBorderコントロールのPaddingプロパティと同じThickness型なので、"左, 上, 右, 下"のようにカンマ区切りで値を指定できます。今回の例では、上下左右に一括で5pxの余白をとりたかったので単に5と指定しています。


このWindowの表示結果を以下に示します。

VerticalAlignmentを設定しているボタンとしていないボタンの表示位置の違いと、Marginを指定しているボタンの周りに余白があることが確認できます。また、水平方向のときと同様に画面からはみ出したものは表示されないことも確認できます。