[WPF] WPF入門 ~レイアウト [Canvas]~

投稿日 : 2009年3月17日 0:36
今回はレイアウトコントロールの1つ、System.Windows.Controls.Canvasコントロールについてです。
では早速MSDNでの説明を見てみましょう。

Canvas は、固有のレイアウト特性を持たない唯一のパネル要素です。子要素のサイズを自動的に設定する要素の子でない限り、Canvas の Height および Width プロパティの既定値は 0 です。Canvas の子要素はサイズ変更されず、単に指定した座標に配置されます。固有のサイズ制約や配置が不要であれば、柔軟な使用が可能です。

上記説明である通りに、Canvasコントロールは座標指定でのレイアウトを行います。
Canvasコントロールは単に子要素が指定した座標に子要素をレンダリングする為、他のPanel独自のロジックを使用するレイアウトコントロールよりパフォーマンスに優れています。

では簡単なCanvasコントロールを使用した例を見てみましょう。

XAML使用例
<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Canvas>
        <Button Canvas.Top="0" Canvas.Left="0" Width="150" Height="25">(Top=0,Left=0)</Button>
        <Button Canvas.Bottom="0" Canvas.Right="0" Width="150" Height="25">(Bottom=0,Right=0)</Button>
    </Canvas>
</Window>

コード使用例(VB)
Class Application
    Private Sub Application_Startup(ByVal sender As Object, ByVal e As System.Windows.StartupEventArgs) Handles Me.Startup
        Dim mainWindow As New Window1()
 
        Dim myCanvas As New Canvas()
 
        Dim button1 As New Button()
        button1.Content = "(Top=0 Left=0)"
        Canvas.SetTop(button1, 0)
        Canvas.SetLeft(button1, 0)
 
        Dim button2 As New Button()
        button2.Content = "(Bottom=0 Right=0)"
        Canvas.SetBottom(button2, 0)
        Canvas.SetRight(button2, 0)
 
        myCanvas.Children.Add(button1)
        myCanvas.Children.Add(button2)
 
        mainWindow.Content = myCanvas
        mainWindow.Show()
    End Sub
End Class

コード使用例(C#)
public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        Window1 mainWindow = new Window1();
 
        Canvas myCanvas = new Canvas();
 
        Button button1 = new Button();
        button1.Content = "(Top=0 Left=0)";
        Canvas.SetTop(button1, 0);
        Canvas.SetLeft(button1, 0);
 
        Button button2 = new Button();
        button2.Content = "(Bottom=0 Right=0)";
        Canvas.SetBottom(button2, 0);
        Canvas.SetRight(button2, 0);
 
        myCanvas.Children.Add(button1);
        myCanvas.Children.Add(button2);
 
        mainWindow.Content = myCanvas;
        mainWindow.Show();
    }
}

 Window1 
上記例のように、Canvasの子要素は添付プロパティを用いてCanvasに対する座標を指定する事によりレイアウトを行います。
Canvasは座標指定の為、Windowコントロールのサイズを変更しても常に指定座標をキープし続けます。

Canvasの添付プロパティには優先順位があります。
  • Top > Bottom
  • Left > Right
このような優先順位がある為、以下のコードではTopとLeftが優先されます。

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Canvas>
        <Button Canvas.Top="0" Canvas.Left="0" Canvas.Bottom="0" Canvas.Right="0" Width="150" Height="25">TopとLeftが優先される</Button>
    </Canvas>
</Window>

Window_2

上記例ではTopプロパティとLeftプロパティがBottomプロパティとRightプロパティより優先されている事が確認出来ます。

また、Canvasコントロールに限ってではありませんが、System.Windows.Controls.Panelクラスを継承しているコントロールではZIndexプロパティを使用して同じ描画領域を共有するコントロールの表示順序を指定する事も出来ます。
既定では表示順序は新しく作成されるコントロールほど上位に描画されるようになります。

下記例では既定の表示順序によるレンダリングです。

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Canvas>
        <Button Canvas.Top="0" Canvas.Left="0" Width="200" Height="170">下位</Button>
        <Button Canvas.Bottom="0" Canvas.Right="0" Width="200" Height="170">上位</Button>
    </Canvas>
</Window>

Window_3

次はZIndexプロパティを使用し表示順序を適用した場合です。

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Canvas>
        <Button Canvas.Top="0" Canvas.Left="0" Canvas.ZIndex="1" Width="200" Height="170">上位</Button>
        <Button Canvas.Bottom="0" Canvas.Right="0" Canvas.ZIndex="0" Width="200" Height="170">下位</Button>
    </Canvas>
</Window>

Window_4

ZIndexプロパティは値が大きい程上にレンダリングされるようになっています。

このように画面レイアウトにおいて、常に同じ位置であるコントロールなどのレイアウトにはCanvasコントロールを使用します。
WPFでは複雑なレイアウトを使用する場合が多々ありますので、描画に関するオーバーヘッドが高くなる傾向があります。
Canvasコントロールは他のレイアウト用コントロールに比べパフォーマンスが高いので、画面レイアウトにて常に固定なコントロールなどではCanvasコントロールを使用する事を検討してみましょう。

今回はレイアウト用コントロールのCanvasコントロールについてでした。

to be continue・・・
コメントの入力
タイトル
名前
Url
コメント