Part 2. Expression Blend との連携
さて、引き続き Part 2 では、Expression Blend との連携方法と、このツールの使い方について解説していきます。
Expression Blend は、WPF や Silverlight 2 で用いられている新しい UI 概念に基づいて作られた UI デザイナツールであり、特にコントロールの配置(レイアウト)の手法に関する考え方が、従来とは全くといっていいほど異なっています。このため、このツールに触れた直後は「どう使えばいいのかさっっっっぱりわからない」になると思いますが、WPF/SL2 の UI 概念とリンクさせながら理解すると、簡単に使いこなせるツールになっています。
というわけで、以下に Expression Blend による画面デザイン手法について解説していきます。ここでは、最終ゴールとして以下のような画面を作るという前提で、この画面を Expression Blend でデザインしていく手法を解説します。
[Step 5] Expression Blend の起動
Expression Blend は、Visual Studio と同じソリューションファイルを利用するため、Visual Studio で開発したプロジェクトをそのまま開くことができます。連携のためのショートカットも用意されており、Visual Studio の開発画面から右クリックを押すことで、Expression Blend を起動することができます。
Expression Blend を起動すると、セキュリティ警告が出ますが、ここではそのまま無視して進んで構いません。完了すると、Expression Blend 上で Visual Studio 2008 の Silverlight 2 プロジェクトが開かれます。
Expression Blend は非常にとっつきにくいツールだと思いますが、いくつか肝になる部分を解説します。
- 画面左側の「オブジェクトとタイムライン」ウィンドウは、XAML ファイルにおけるコントロールのツリー構造を表現したものです。基本的には、このウィンドウを利用して画面を組み立てます。
- 画面中央部の上側は XAML のプレビュー画面、下側は XAML のコードです。XAML のプレビュー画面は VB のフォームのようにいじる(コントロールの位置を動かしたりする)ことができますが、絶対に安易にいじってはいけません。後述するレイアウトコントロールの概念を理解してからいじるようにしてください。
- 画面右側には、「プロジェクト」ウィンドウと、「プロパティ」ウィンドウがあります。
- これらのウィンドウは、ツール→オプション→ワークスペース→ワークスペースのズームの項目から、縮小・拡大表示することができます。特に画面が狭い PC を使っている場合には、この拡大率を下げると使いやすくなりますので活用してください。
さて、ここから Expression Blend での画面デザイン方法について解説していきますが、その前に、Silverlight 2 では大別して 2 つの基本的なレイアウト方式がサポートされている点を理解しておく必要があります。それが、固定座標レイアウトと、リキッドデザインレイアウトです。
- 固定座標レイアウトとは...
いわゆる従来の VB 6 や Windows フォームのアプリケーションに代表されるような、「固定サイズ画面の固定ピクセル位置に固定サイズのコントロールが貼り付けられている」画面。 - リキッドデザインレイアウトとは...
Office や Windows Messenger のように、画面サイズを変えると「液体のように」その画面サイズに追随するようにレイアウトがきれいに変わっていくタイプの画面。
VB6 をはじめとしたフォーム系アプリケーション開発技術の多くは、固定座標レイアウトをベースとしていましたが、昨今のアプリケーションでは、リキッドデザインに対応することが求められるようになってきました。たとえば、今この文章を書くのに使っている Live Writer も、ウィンドウサイズ変更時に動的に入力欄のサイズが変更されるようになっています。
リキッドデザインに対応することは、ウィンドウサイズの観点でだけでなく、多言語対応の観点でも重要です。たとえば利用する OS の言語によって
と表示を切り替えるようなボタンを用意しようと思ったとき、(コンテンツの最大サイズに合わせてボタンの Width プロパティを設定しておくのではなく)、コンテンツのサイズに合わせて、柔軟にコントロールのサイズやレイアウトが変わってくれることが望ましいといえます。
Silverlight 2 では、UI コントロールを並べる際に、代表的に以下の 3 通りの並べ方がサポートされています。
- Canvas : 固定座標レイアウト
- Grid : リキッドデザインレイアウト
- StackPanel : 横または縦に並べるだけの単純なレイアウト
StackPanel の使い方についてはすでに解説済みなので、引き続き、Canvas レイアウトと Grid レイアウトについて解説します。
[Step 6] レイアウトコントロール① Canvas コントロール
ここまでのサンプルでは、StackPanel レイアウトコントロールの中に TextBox, TextBlock, Button を並べましたが、これらを固定座標レイアウト(いわゆるフォームに対して任意の位置に貼り付けられるレイアウト)にしてみます。
まず、Expression Blend のオブジェクトとタイムラインウィンドウから、StackPanel コントロールを Canvas コントロールに差し替えます。(右クリック→レイアウトの種類の変更→Canvas を選択)
これにより、以下の点が変化します。
- オブジェクトとタイムラインウィンドウの StackPanel が Canvas にかわります。
- XAML コード内の StackPanel タグが Canvas タグにかわります。
この状態になると、画面上の UI コントロールを任意の場所に動かしたり、サイズを自由に変更したりすることができます。(レイアウト情報は XAML コードに属性情報として保存されます。)
1: <UserControl x:Class="SilverlightApplication1.Page"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: Width="400" Height="300">
5: <Canvas>
6: <TextBox x:Name="textBox1" Text="Nobuyuki" Height="20.7724609375" Width="148" Canvas.Top="119.309" Canvas.Left="132" />
7: <TextBlock x:Name="textBlock1" Text="あああ" Height="22.537109375" Width="158" Canvas.Top="92.772" Canvas.Left="44" />
8: <Button x:Name="button1" Content="ボタン" Click="button1_Click" Height="25.90283203125" Width="136" Canvas.Top="41.31" Canvas.Left="144" />
9: </Canvas>
10: </UserControl>
さて、Silverlight 2 では、UI コントロールの入れ子関係が非常に重要な意味を持ちます。例えば、Canvas (いわゆるパネル)の中に Canvas が貼り込まれている場合、新たに画面に貼り付ける部品(Button や TextBox コントロール)が、どちらの Canvas に所属するのかは非常に重要になります。
上図の場合、Button コントロールがどちらの Canvas に所属しているかは、XAML コントロールツリー(オブジェクトとタイムラインウィンドウ)を見るとすぐにわかります。
このような理由から、コントロールを追加する場合は、安易にドラッグ&ドロップで画面上に追加しないようにしてください。一番確実なのは、下図のように、コンテナとなるコントロールをダブルクリックして選択したのちに、左側のツールボックス上のアイテムをダブルクリックしてアイテムを追加する方法です。ツールに慣れるまではこの手法を使っていただいたほうがよいでしょう。
[Step 7] レイアウトコントロール② Grid コントロール
さて、Canvas レイアウトコントロールは固定座標レイアウトを行うために使うものでしたが、リキッドデザイン画面を実現したい場合には、Grid レイアウトコントロールをコンテナとして利用します。
Grid レイアウトコントロールの基本概念は、「パネルを(Excel のような)複数のセルに切り、そのセルにコントロールを割り当てていく」というものです。(概念をわかりやすく説明するためにあえて Excel のスナップショットを示しますが^^)、下図のように、Excel と同様、複数の列や行を連結させてひとつのセルとして使うことができるようになっています。
では実際に、リキッドデザインに対応した下図のような画面を Expression Blend で作成してみることにします。
Page.xaml ファイルにはすでにかなりの修正が加えられてしまっていますので、いったんクリーンアップすることにしましょう。
- Expression Blend 上で Page.xaml ファイルを削除します。(「プロジェクトから削除」ではなく、通常の「削除」を行い、ファイルを完全に消去します。)
- 新しいユーザコントロールとして Page.xaml ファイルを追加してください。(プロジェクトに Silverlight 2 ユーザコントロールを Page.xaml という名称で追加します。)
新規に追加した Page.xaml ファイルは Grid レイアウトコントロール(既定のデザインサイズは 640x480)になっていますので、こちらを使って、リキッドデザインの画面を設計していきます。
- 既定のレイアウトコントロールのサイズではやや大きすぎるという場合には、XAML コード中の x:DesignWidth と x:DesignHeight 属性を変更しておいてください。
- なおこれらの属性は、Expression Blend 上でのデザイン時のサイズであり、実際の実行時の描画サイズではありません。実際の描画時のサイズを直接指定したい場合には、Width, Hieght 属性を使います。
1: <UserControl
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: mc:Ignorable="d"
7: x:Class="SilverlightApplication1.Page"
8: d:DesignWidth="400" d:DesignHeight="300">
9:
10: <Grid x:Name="LayoutRoot" Background="White" />
11: </UserControl>
では、リキッドデザイン画面を作成していきます。まず、画面を 3x2 のセルに切ります。
- パネルの上・左部分のところでマウスをクリックすると、行や列を切ることができます。
- 幅についてはとりあえず適当で OK です。(あとから調整します。)
次に、画面上に UI コントロールを配置していきます。
- Grid レイアウトコントロール上に、TextBlock, Button, ListBox コントロールを追加します。
- 追加の際は、デザイン画面上にドラッグ&ドロップするのではなく、① 「オブジェクトとタイムライン」ウィンドウ上の Grid コントロール(オブジェクト名 LayoutRoot )をまずダブルクリックして選択し、② ツールボックス上のコントロールをダブルクリックします。これにより、Grid レイアウトコントロール下に、TextBlock, Button, ListBox コントロールが追加されます。
- この時点では、レイアウトを設定していないので、グリッドの左上に 3 つのコントロールが貼りついている形になっています。
次に、これらの貼り付けたコントロールを、本来の正しいセルの位置に移していきます。最終的には、各コントロールを下図のように配置させます。
例えば ListBox コントロールを、下側の行の 3 つのセルにまたがって配置させるためには、以下のように作業します。
- まず、オブジェクトとタイムラインウィンドウで、ListBox を選択します。
- ツールボックス内のポインタ(左上のもの)を選択し、ListBox を動かします。
- ガイドが表示されるので、これに割り当てます。(割り当て時は、隙間(マージン)を取っても OK ですし、マージンを取らずにぴったり割り当てても OK です。お好みでどうぞ。)
これらを繰り返して、TextBlock, Button, ListBox を正しい位置に配置します。
完成した XAML コードは以下の通りです。(RowDefinition, ColumnDefinition の項目は、セルの切り方によって若干異なるはずです)
1: <UserControl
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: mc:Ignorable="d"
7: x:Class="SilverlightApplication1.Page"
8: d:DesignWidth="400" d:DesignHeight="300">
9:
10: <Grid x:Name="LayoutRoot" Background="White" >
11: <Grid.RowDefinitions>
12: <RowDefinition Height="0.2*"/>
13: <RowDefinition Height="0.8*"/>
14: </Grid.RowDefinitions>
15: <Grid.ColumnDefinitions>
16: <ColumnDefinition Width="0.238*"/>
17: <ColumnDefinition Width="0.537*"/>
18: <ColumnDefinition Width="0.225*"/>
19: </Grid.ColumnDefinitions>
20: <TextBlock HorizontalAlignment="Left" VerticalAlignment="Stretch" Text="TextBlock" TextWrapping="Wrap" d:LayoutOverrides="Width" Margin="8,8,0,8" Width="79.2"/>
21: <Button Margin="8,8,8,8" Content="Button" Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
22: <ListBox Margin="8,8,8,8" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.ColumnSpan="3"/>
23: </Grid>
24: </UserControl>
この中で注目したいコードは以下の 3 行です。
1: <TextBlock HorizontalAlignment="Left" VerticalAlignment="Stretch" Text="TextBlock" TextWrapping="Wrap" d:LayoutOverrides="Width" Margin="8,8,0,8" Width="79.2"/>
2: <Button Margin="8,8,8,8" Content="Button" Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
3: <ListBox Margin="8,8,8,8" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.ColumnSpan="3"/>
- Grid.Column(列), Grid.Row(行) 属性により、当該コントロールが占有するセルが指定されます。
- Grid.ColumnSpan(そこから横に何セルを結合して使うか)、Grid.RowSpan(そこから下に何セルを結合して使うか)により、セルを結合して使うことが指定されます。
- HotizontalAlignment, VerticalAlignment が Stretch になっているため、各コントロールは「与えられたセルをめいいっぱい使って」描画します。
ここまでの状態で、Visual Studio 2008 に戻って実行してみると(SilverlightApplication1TestPage.aspx を表示してみると)、以下のようになります。
[ウィンドウ拡大時]
[ウィンドウ縮小時]
確かにリキッドデザインにはなっているものの、画面が崩れてしまうことが確認できます。これを防ぐため、Grid レイアウトコントロールに、サイズに関する制約条件を追加して、適切に動作するようにします。
[Step 8] サイズ制約条件の追加
再び Expression Blend の画面に戻って作業します。
- オブジェクトとタイムラインのウィンドウから、Grid レイアウトコントロール(オブジェクト名は LayoutRoot)をダブルクリックして選択します。
- 選択すると、黄色いボーダーラインが付与され、コンテナとしての各種の情報がエディットできるようになります。
各列・各行に、鍵のアイコンが付与されていますが、この鍵のアイコンをクリックすると、以下の 3 つの状態をトグルするようになっています。
- スターサイズ設定済み : 余っている幅を使う
- ピクセルサイズ設定済み : 固定的なサイズに設定する
- 自動サイズ設定済み : 内容を表示するために必要な最低限のサイズを利用する
リキッドデザイン画面を構成する際に、この中で最も重要なのが「自動サイズ設定済み」です。この設定を行うと、コンテンツのサイズに合わせて幅が自動調整されます。そこで、1 行目、1 列目、3 列目に対して「自動サイズ」を設定します。(鍵のアイコンの一部が変化していることに注目してください。)
この設定だけだと見た目が変わりません。これは、各列・各行に最低割り当てピクセル(MinWidth, MinHeight)が設定されてしまっているためです。
1: <Grid.RowDefinitions>
2: <RowDefinition Height="Auto" MinHeight="60"/>
3: <RowDefinition Height="*"/>
4: </Grid.RowDefinitions>
5: <Grid.ColumnDefinitions>
6: <ColumnDefinition Width="Auto" MinWidth="95.199996948242188"/>
7: <ColumnDefinition Width="*"/>
8: <ColumnDefinition Width="Auto" MinWidth="89.916000366210938"/>
9: </Grid.ColumnDefinitions>
これらの設定を削ると、コンテンツに合わせたサイズでセルの幅や高さが設定されるようになります。やり方はいくつかありますので、お好きな方法を使ってください。
- XAML のコードエディタから、これらの設定を削ってしまう。(てっとり早いです^^)
- Grid コントロールのプロパティを開き、「レイアウト」の項目の中の ColumnDifinitions, RowDifinitions コレクションの設定を変更する。(※ 既定では折りたたんで隠されているので、開いて使ってください)
- デザイン画面上で列幅や行幅を変更し、なるべく小さな幅にする。(MinWidth, MinHeight を小さな値にする) (GUI 上からできるのでこれも便利です。)
以上の結果、どのような動作をすることになるかというと、
- 横方向について
1 列目と 3 列目について、「コンテンツのサイズに合わせた最小幅」がまず割り当てられる。
2 列目については、残った幅が割り当てられる。
- 縦方向について
1 行目について、「コンテンツのサイズに合わせた最小幅」がまず割り当てられる。
2 行目については、残った幅が割り当てられる。
以上の作業で、リキッドデザインの画面が出来上がります。
[Step 9] 最後の仕上げ
最後に、TextBlock や Button への変数名の設定や、文字列の変更を Expression Blend から行っておきます。
- TextBlock コントロールの Text プロパティを「著者データ一覧」に変更する。
- Button コントロールの Content プロパティを「一覧表示」に変更する。
私の端末上で作業してみたら、下図のように TextBlock 内のテキストが折り返されてしまいましたが、これは TextBlock に Width プロパティがついていたためでした;。
というわけで Width プロパティを削除(Auto に変更)。ちなみに、リキッドデザイン画面を作成する場合には、極力 Width プロパティや Height プロパティを使わないようにすることをお勧めします。(リキッドデザイン画面のレイアウトの考え方は、レイアウトの制約条件を設定する、という考え方であるため。なので、MinWidth や MaxWidth といったプロパティを中心に設定していきます。)
最後に変数名を設定しておきます。(プロパティウィンドウの名前のところから設定)
- TextBlock コントロール → textBlock1
- Button コントロール → button1
- ListBox コントロール → listBox1
完成した画面と XAML コードを以下に示します。
1: <UserControl
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: mc:Ignorable="d"
7: x:Class="SilverlightApplication1.Page"
8: d:DesignWidth="400" d:DesignHeight="300">
9:
10: <Grid x:Name="LayoutRoot" Background="White" >
11: <Grid.RowDefinitions>
12: <RowDefinition Height="Auto"/>
13: <RowDefinition Height="*"/>
14: </Grid.RowDefinitions>
15: <Grid.ColumnDefinitions>
16: <ColumnDefinition Width="Auto"/>
17: <ColumnDefinition Width="*"/>
18: <ColumnDefinition Width="Auto"/>
19: </Grid.ColumnDefinitions>
20: <TextBlock HorizontalAlignment="Left" VerticalAlignment="Stretch" Text="著者一覧表示" TextWrapping="Wrap" Margin="8,8,8,8" Width="Auto" x:Name="textBlock1"/>
21: <Button Margin="8,8,8,8" Content="一覧表示" Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" x:Name="button1"/>
22: <ListBox Margin="8,8,8,8" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.ColumnSpan="3" x:Name="listBox1"/>
23: </Grid>
24: </UserControl>
以上で Expression Blend を使った画面の作成方法についての説明はおわりです……というかめっちゃ長すぎる;。もっと短いはずだったんですが、文字で書くと長くなっちゃいますね。すみません;;。キーポイントをまとめると、以下のようになります。
- Silverlight 2 では、大別して 3 種類のレイアウトが利用できる。
① Canvas : 固定座標レイアウト
② Grid : リキッドデザインレイアウト
③ StackPanel : 横または縦に並べるだけの単純なレイアウト
- UI コントロールを貼り付ける場合には、入れ子関係に注意する。
- Grid を使う場合には、まずおおざっぱにセルを切った後、セル幅に「自動サイズ設定」を指定していく。
引き続き、Part 3. では ListBox コントロールへのデータの一覧表示機能の作り込みなどについて説明していきたいと思います。