第1回 WPFとSilverlightをまとめて習得しよう連載 WPF/Silverlight UIフレームワーク入門(4/4 ページ)

» 2009年04月03日 00時00分 公開
[八巻雄哉グレープシティ株式会社]
前のページへ 1|2|3|4       

■コントロールの種類

 レイアウトを押さえたら次に重要となるのは、そこに配置するコントロールである。WPF UIフレームワークのコントロールは、その多くがこれまでのWin32コントロールを再現したものであり、同じ名称のコントロールにおいて個々の役割に大きな違いはない。

 一方、コントロール全般としては、新しい概念や機能がいくつか存在する。ここではそのうちの1つであるコンテンツ・モデルを紹介する。

コンテンツ・モデル

 コンテンツとは内容や中身といった意味であり、例えばTextBoxコントロールのコンテンツといえば表示(入力)される文字列(Textプロパティに設定された値)となる。TextBoxの場合、その名前が示すように文字列以外がコンテンツになるということは基本的にないはずだ。

 それでは、Buttonコントロールについてはどうだろうか? こちらも表示される文字列がコンテンツになると思われるかもしれないが、実際にはそれ以外の要素が存在するケースもある。次の画面を見てほしい。

Windowsフォームで作成したアイコン付きボタン


 上の画面のようなアイコン付きのボタンの場合、画像と文字列の2つのコンテンツが存在する。WindowsフォームのButtonコントロールの場合であれば、Textプロパティに文字列を、Imageプロパティに画像を設定し、お互いの位置関係を、TextImageRelationプロパティを使って指定することで、上記のようなアイコン付きボタンを作成できる。

 しかしながら、このようなアイコン付きボタンをいとも簡単に実現できたのは、WindowsフォームのButtonコントロールに画像を表示するためのImageプロパティが用意されていたからにほかならない。例えば同じWindowsフォームのDataGridViewコントロールの列ヘッダ部分で同様の表示を行おうと思うと、たちまち多量のコーディングが必要となる。つまり、これまでのコントロールは事実上コンテンツが制限されていたと考えることができる。

 前置きが長くなったが、WPF UIフレームワークでは「コンテンツ・モデル」という概念を導入することで、この制限が完全に撤廃された。つまり、WPF UIフレームワークでは、TextBoxコントロールなどのようにその目的・役割から必然的にコンテンツが限定されるコントロールを除き、さまざまなコンテンツを自由に設定することが可能となっているのである。

 ここでは、単一のコンテンツを持つ「ContentControlタイプ」と、複数のコンテンツを持つ「ItemsControlタイプ」という2つのタイプのコンテンツ・モデルを紹介する(この両者はControlクラス(System.Windows.Controls名前空間)を継承しているため、「Controlコンテンツ・モデル」とも呼ばれる)。

ContentControlタイプのコンテンツ・モデル

 ContentControlクラスはContentプロパティを持っており、このプロパティは文字列に限らず画像やUI要素といったさまざまなオブジェクトを設定することが可能になっている。代表的なContentControlタイプのコントロール(=ContentControlクラスから派生しているコントロール)としては、Button、CheckBox、RadioButtonなどがある。

 Buttonコントロールを例にして説明しよう。先ほどまでPanelの説明で使用していたButtonコントロールでは、下記のコードのようにContentプロパティに文字列(Stringオブジェクト)を設定していた。

<Button Content="管理者実行"/>

プロパティ属性構文を使用してStringオブジェクトをContentプロパティに設定したコード例

StringオブジェクトがContentプロパティに設定されたButtonコントロールの表示例


 Contentプロパティは基本的にはどんなオブジェクトでも設定可能であるため、下記のようにプロパティ要素構文を使用してImageオブジェクトを設定することもできる。

<Button>
  <Button.Content>
    <Image Source="uac.png"/>
  </Button.Content>
</Button>

ImageオブジェクトをContentプロパティに設定したコード例

ImageオブジェクトがContentプロパティに設定されたButtonコントロールの表示例


 どんなオブジェクトでも設定することはできるが、Contentプロパティに設定できるオブジェクトは1つだけである。ではアイコン付きボタンのように画像と文字列といった2つのオブジェクトをコンテンツにしたい場合にはどうすればよいのか?

 2つ以上の要素を表示させたい場合には、レイアウトの項で説明したPanelを利用することになる。下の画面はその例だ。

2つ以上の要素をPanelにまとめてContentプロパティに設定したButtonコントロールの表示例


<Button>
  <Button.Content>
    <StackPanel Orientation="Horizontal">
      <Image Source="uac.png"/>
      <TextBlock
          Text="管理者実行" VerticalAlignment="Center"/>
    </StackPanel>
  </Button.Content>
</Button>

2つ以上の要素をPanelにまとめてContentプロパティに設定したButtonコントロールのコード例

 上記のようにContentプロパティにはStackPanelを設定し、Image要素とTextBlock要素はそのStackPanelに配置する。実はこんなところでもPanelによるレイアウト機能が重要となってくる。

 Contentプロパティのようなコンテンツを設定するためのプロパティは「コンテンツ・プロパティ」と呼ばれ、プロパティ要素構文で記述する場合には、下記のコードのようにプロパティ名(上記のコードでは<Button.Content>タグ)を省略できる。

<Button>
  <StackPanel Orientation="Horizontal">
    <Image Source="uac.png"/>
    <TextBlock
        Text="管理者実行" VerticalAlignment="Center"/>
  </StackPanel>
</Button>

「<Button.Content>」というプロパティ名を省略したButtonコントロールのコード例

 省略できると述べたが、正確には省略することが推奨されており、記述方法に「コンテンツ・プロパティ構文」という名前まで付いている。XMLでは開始タグと終了タグで囲まれた部分を「コンテンツ」と呼ぶため、これに合わせた記述方法であると思われる。

 今回の例がアイコン付きボタンということで、コンテンツは画像と文字列という比較的一般的なものであったが、何度もいうようにコンテンツとして格納できるオブジェクトに制限はない。MSDNライブラリにもそのように書いてあるので安心してほしい。いろいろな組み合わせを試してみるとよいだろう。

ItemsControlタイプのコンテンツ・モデル

 単一のコンテンツを表示するContentControlタイプに対し、複数のコンテンツを表示するのがItemsControlタイプだ。

 ItemsControlクラスは、Itemsプロパティというコンテンツ・プロパティを持っており、このプロパティに対してさまざまなオブジェクトを複数個設定することが可能になっている。代表的なItemsControlタイプのコントロール(=ItemsControlクラスから派生しているコントロール)としては、ComboBox、ListBox、TabControlなどがある。

 ここではListBoxコントロールを例に解説していこう。

 Windowsフォームに代表されるようなこれまでのListBoxコントロールでは、項目に表示できるのは基本的に文字列のみであった。WPF UIフレームワークのListBoxコントロールは、コンテンツ・プロパティであるItemsプロパティに設定された要素が項目として表示される。次の画面はその実行例である。

複数の要素が項目としてItemsプロパティに設定されたListBoxコントロールの表示例

<ListBox>
  <StackPanel Orientation="Horizontal">
    <Image Source="Black.png" Height="100"/>
    <TextBlock
        Text="Zune Black" VerticalAlignment="Center"/>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <Image Source="Brown.png" Height="100"/>
    <TextBlock
        Text="Zune Brown" VerticalAlignment="Center"/>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <Image Source="White.png" Height="100"/>
    <TextBlock
        Text="Zune White" VerticalAlignment="Center"/>
  </StackPanel>
</ListBox>

複数の要素が項目としてItemsプロパティに設定されたListBoxコントロールのコード例
「<ListBox.Items>」というプロパティ名を省略している。

 先ほどのアイコン付きボタンの例と同様、StackPanelを使って画像と文字列を配置している。異なるのはそれを1つではなく3つ、コンテンツ・プロパティとして設定している点だ。もちろんContentControlタイプと同様、こちらもコンテンツとして格納できるオブジェクトに制限はない。

 ところでコンテンツ・プロパティであるItemsプロパティに対して、複数の項目、つまり複数のオブジェクトを設定するということに少々違和感を覚えた方もいるのではないだろうか。Itemsプロパティに複数のオブジェクトを設定するという処理をC#やVBで記述すると、下記のようになる。

ItemCollection ItemCollection1 = ListBox1.Items;
ItemCollection1.Add(new TextBlock() { Text = "項目1" });
ItemCollection1.Add(new TextBlock() { Text = "項目2" });
ItemCollection1.Add(new TextBlock() { Text = "項目3" });

Dim ItemCollection1 As ItemCollection = ListBox1.Items
ItemCollection1.Add(New TextBlock With {.Text = "項目1"})
ItemCollection1.Add(New TextBlock With {.Text = "項目2"})
ItemCollection1.Add(New TextBlock With {.Text = "項目3"})

Itemsプロパティに3つのTextBlockコントロールを追加するコード(上:C#、下:VB)

 ItemsプロパティはItemCollectionというコレクション型で、ItemCollection.Addメソッドを使ってコレクションにオブジェクトを追加できる。

 WPF UIフレームワークでは、コレクション型のプロパティは必ず空のコレクション・インスタンスを既定値として持っている。そして、XAMLでコレクション型のプロパティに要素が設定されている場合、そのコレクションのAddメソッドが暗黙的に呼び出されてコレクションに追加されるという仕組みになっている。XAML構文では、これを「暗黙的なコレクション構文」と呼ぶ。

 なお、XAMLで記述可能であれば、基本的にはそれと同じ内容をC#やVBといったコードでも記述できる。XAMLの構文がどうも理解できないというときには、それをC#やVBで書くとどうなるのかといったアプローチで調べてみるとよいだろう。

コントロールの種類のまとめ

 コンテンツ・モデルという観点からコントロールを種別すると、以下の4つに分けることができると筆者は考える。

コンテンツ・モデルのタイプ コントロール
任意の単一コンテンツを持つ(ContentControl) Button、CheckBox、RadioButton
任意の複数コンテンツを持つ(ItemsControl) ComboBox、ListBox、TabControl
コンテンツを持たない ProgressBar、ScrollBar、Slider
限定されたコンテンツを持つ TextBox、PasswordBox
コンテンツ・モデルという観点でまとめたコントロールの分類

 コントロールの種類という観点からコンテンツ・モデルをご紹介したが、コントロール以外でもコンテンツ・モデルをサポートしているものがある。それは冒頭に説明したPanelだ。PanelはChildrenプロパティがコンテンツ・プロパティとなっており、実はPanelにUI要素を配置するというのは、このChildrenプロパティが持っているUIElementCollectionコレクションにAddメソッドを使ってUI要素を追加しているということになる。

 ただし、Panelの場合には、ContentControlタイプやItemsControlタイプのコントロールと違い、UI要素(=UIElementクラス、およびその派生クラス)しかコンテンツとして持つことができないので、注意が必要だ。


 以上、今回はレイアウトの基本となるPanelと多くのコントロールがサポートしているコンテンツ・モデルを解説した。次回はWPF UIフレームワークの要ともいえるデータ・バインディングをご紹介する予定だ。お楽しみに。

「連載 WPF/Silverlight UIフレームワーク入門」のインデックス

連載 WPF/Silverlight UIフレームワーク入門

前のページへ 1|2|3|4       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。