WPF アプリケーションを作る クッキング ガイド

第 2 回 「私のアプリはオシャレ好き ~表示系のプロパティをマスターしよう~」

『WPF アプリケーションを作る クッキング ガイド』とはこれから WPF (Windows Presentation Foundation) アプリケーション開発に取り掛かる方向けに、そのエッセンスを解説する記事です。

前回では、レイアウトについて解説いたしましたが、今回、そして次回の 2 回では、そのレイアウト内に設置する様々なオブジェクトの表示や動作を定義するプロパティについて解説いたします。

流れとしては、大きく分けて下記の 3 種類のプロパティについて解説していきます。

  • サイズを定義するプロパティ
  • 配置を定義するプロパティ
  • 変形を定義するプロパティ

これらのレイアウトプロパティはどれも、FrameworkElement の基本クラスから継承され、ほとんどのユーザー インターフェイス オブジェクトで設定可能です。
これらのプロパティを使いこなすことで、XAML をコードビューで直書きする際にも、手軽に様々な表示や動作を設定することが可能となります。

オブジェクトのサイズを設定するプロパティ

まず初めはオブジェクトの横幅や高さなど、大きさを設定するプロパティです。様々な言語やオーサリングツールで、ごく基本的なプロパティとして存在しているものと変わりませんので、特に難しいことはありません。まず、下記のコードをご覧ください。

<Button Width="100" Height="100" Content="Sample" />

図1. オブジェクトのサイズを指定した場合の実行結果

図1. オブジェクトのサイズを指定した場合の実行結果

 

プロパティ名

指定可能な値

デフォルト

Width

ピクセル値 (double), Auto

Auto

Height

ピクセル値 (double), Auto

Auto

Width がオブジェクトの横幅、Height がオブジェクトの高さを、それぞれ指定しています。これらの値を変更してみてください。それぞれ縦横の大きさが変わるのが確認できると思います。
なお、これらの値にAutoを指定していると、横幅や高さは、そのオブジェクトの配置されているレイアウト コントロール内で可能な大きさに自動的に調整されます。

特定の機種や使用環境のみを対象として、画面サイズや配置を固定したアプリケーションを作成したい場合、この Width や Height などのプロパティを使用することになるでしょう。
ただ WPF では、基本的にはオブジェクトの大きさを絶対値で指定することを推奨していません。なぜなら、コンテンツの拡大縮小や移動に併せてオブジェクトの大きさが自動的に調整される方が、ユーザー インターフェイスの変更の際にいちいち余計な作業が発生せず、ユーザー インターフェイス制作上の工数の削減につながりやすいからです。また、そのローカライズや転用の際にも、作業が楽になります。WPF アプリケーションでは、オブジェクトの大きさを絶対指定しない限りは、そのオブジェクトは可能なサイズまで引き延ばされて表示されます。
そのように、大きさが自動調整される場合には、下記のプロパティを併せて使用することになります。下記のコードをご覧ください。

<Button MinWidth="40" MinHeight="40" MaxWidth="120" MaxHeight="120" Content="Sample"/>

プロパティ名

指定可能な値

デフォルト

MinWidth

ピクセル値 (double), Auto

Auto

MinHeight

ピクセル値 (double), Auto

Auto

MaxWidth

ピクセル値 (double), Auto

Auto

MaxHeight

ピクセル値 (double), Auto

Auto

これらのプロパティを使用することで、オブジェクトの横幅や高さの自動調整がなされる際に、それらの値の上限値および下限値を設定することが可能となります。自動調整がなされるように設定していたとしても、ユーザーの操作によっては、そのインターフェースの配置(ないしは制作者の狙い)にそぐわないようなウインドウサイズにされてしまう場合もあるかもしれません。ユーザー インターフェース デザイナー(そして XAMLer の皆様方・・)としては、オブジェクト サイズを自動調整の設定にしていたとしても、これらのプロパティを積極的に利用することで、どんな場面でもレイアウトが崩れないように様々な対策を施すことが必要となるでしょう。

オブジェクトの配置を設定するプロパティ

オブジェクトの配置を設定するのも、ごく基本的なプロパティと言えるでしょう。下記のコードをご覧ください。

<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" Width="Auto" Height="Auto" x:Name="DockPanel">

    <Button HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="100" x:Name="Button" Content="Sample"/>

</DockPanel>

図2. オブジェクトの配置を指定した場合の実行結果

図2. オブジェクトの配置を指定した場合の実行結果

 

プロパティ名

指定可能な値

デフォルト

HorizontalAlignment

Left, Center, Right, Stretch

Stretch

VerticalAlignment

Top, Canter, Bottom, Stretch

Stretch

HorizontalAlignment は横方向に関して、VerticalAlignment は縦方向に関して、それぞれオブジェクトが配置されているレイアウト内の余白領域の処理方法を設定します。何も指定しない場合は、デフォルト値として Stretch が適用され、余白をすべて埋めるよう、それぞれ縦横拡大されて表示されます。これをオブジェクトの高さや幅はそのままで、引き延ばさないで配置するようにしたい場合は、これらを "Left", "Center", "Right" あるいは "Top", "Canter", "Bottom" を指定することになります。オブジェクトは引き延ばされず、指定した位置に配置され、余白は埋められません。
試しに、上記コードで HorizontalAlignment の値を Center や Right に変えてみてください。オブジェクトの配置が変わるのが確認できるかと思います。
また、Stretch を設定するか、このプロパティの指定を削除してしまえば、ボタンの幅が引き延ばされて表示されます。

次に、余白の設定です。ここでいう余白とは、レイアウト内でオブジェクトの周囲部分に残す隙間のことです。次のコードをご覧ください。

<Grid.ColumnDefinitions>
   <ColumnDefinition Width="0.5*"/>
   <ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button1" Content="Sample1" Grid.Column="0" />

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" x:Name="Button2" Content="Sample2" Grid.Column="1" />

図3. Margin プロパティで余白を指定した場合の実行結果

図3. Margin プロパティで余白を指定した場合の実行結果

 

プロパティ名

指定可能な値

デフォルト

Margin

ピクセル値 (double), ピクセル値 (Thickness)

-

Margin プロパティを設定することで、オブジェクトの配置可能な領域内での、オブジェクト周りの余白分を調整することが可能です。
単一のピクセル値を指定することで、上下左右均等の余白を指定することも可能ですし、40, 30, 40, 30 というように Tchickness 構造体で Left, Top, Right, Bottom それぞれの余白の値を記述することで、均一ではなくバラバラの値を適用することも可能です。
あるレイアウト内に配置したそれぞれのオブジェクト間の隙間を一様に設定したい時などは、レイアウト自体の作りで余白の領域を設定していくのではなく、この Margin プロパティを使用して設定していく方が、シンプルなコードにできます。

また、上記と似ていますが、下記のコードをご覧ください。

<Grid.ColumnDefinitions>
   <ColumnDefinition Width="0.5*"/>
   <ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button1" Content="SampleSampleSample" Grid.Column="0" Padding="0" />

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button2" Content="SampleSampleSample" Grid.Column="1" Padding="60"/>

図4. Paddingプロパティで余白を指定した場合の実行結果

図4. Paddingプロパティで余白を指定した場合の実行結果

 

プロパティ名

指定可能な値

デフォルト

Padding

ピクセル値 (double), ピクセル値 (Thickness)

0

Margin とは異なり、オブジェクトの周囲ではなくオブジェクト内での余白を指定するプロパティが、Padding です。ボタンなどでは通常、そのボタンの中にテキストや画像が入りますが、それら内側の要素と、ボタン自体の枠との隙間を調整するのが Padding です。
なお、WPF のすべてのオブジェクトでこの Padding プロパティが使える訳ではありません。すべてのオブジェクトがボタンコントロールのように、内側に子要素を持てるわけではありませんので、それら子要素を持たないオブジェクトでは Padding プロパティを指定しても特に意味はありません。

変形を定義するプロパティ

オブジェクトの拡大縮小・回転などを設定するプロパティも用意されています。これらのプロパティを設定すると、その設定した結果に応じて、オブジェクトの座標変換が自動的に行われます。下記のコードをご覧ください。

<Grid.ColumnDefinitions>
   <ColumnDefinition Width="0.25*"/>
   <ColumnDefinition Width="0.25*"/>
   <ColumnDefinition Width="0.25*"/>
   <ColumnDefinition Width="0.25*"/>
</Grid.ColumnDefinitions>

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button1" Grid.Column="0" >
   <TextBlock>
      <TextBlock.RenderTransform>
         <ScaleTransform ScaleX="3" ScaleY="3" />
      </TextBlock.RenderTransform>
      SampleSample
   </TextBlock>
</Button>

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button2" Grid.Column="1" >
   <TextBlock>
      <TextBlock.RenderTransform>
         <RotateTransform Angle="50" />
      </TextBlock.RenderTransform>
      SampleSample
   </TextBlock>
</Button>

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button3" Grid.Column="2" >
   <TextBlock>
      <TextBlock.LayoutTransform>
         <ScaleTransform ScaleX="3" ScaleY="3" />
      </TextBlock.LayoutTransform>
      SampleSample
   </TextBlock>
</Button>

<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" x:Name="Button4" Grid.Column="3" >
   <TextBlock>
      <TextBlock.LayoutTransform>
         <RotateTransform Angle="50" />
      </TextBlock.LayoutTransform>
      SampleSample
   </TextBlock>
</Button>

図5. オブジェクトの変形の実行結果

図5. オブジェクトの変形の実行結果

 

プロパティ名

指定可能な値

デフォルト

RenderTransform

ScaleTransform, RotateTransform

 

LayoutTransform

ScaleTransform, RotateTransform

 

ScaleTransform.ScaleX

横方向の拡大倍率 (double)

1

ScaleTransform.ScaleY

縦方向の拡大倍率 (double)

1

RotateTransform.Angle

回転角度

 

RenderTransform、LayoutTransforma には様々な値を指定できます。ScaleTransform の属性値として、横軸の引き延ばし度合いを指定する ScaleX 、縦軸の引き延ばし度合いを指定する ScaleY 。また、RotateTransform の属性値として、回転の度合いを設定する Angle などがあります。

RenderTransform と LayoutTransform の違いは、その座標変換の結果がレイアウトに影響するかどうかです。
前者は、座標変換の結果、そのオブジェクトに割り当てられたレイアウトやサイズからはみ出ることになったとしても、その周りのレイアウトへは影響を及ぼしません。具体的には、上記サンプルコードのボタン 1、2 のように、テキストの入ったボタンで、中身のテキストに RenderTransform でサイズを変えたとしても、ボタン自体の大きさは変わらず、中のテキストははみ出します。
後者は、座標変換の結果がそのオブジェクトに割り当てられたレイアウトや領域からはみ出す場合は、自動的にオブジェクトの大きさが調整されます。具体的には、上記サンプルコードのボタン 3、4 のように、テキストの入ったボタンで、中身のテキストに LayoutTransform で拡大処理をさせると、その拡大された結果に応じて、ボタンに入りきるよう、テキストのサイズが自動調整されます。

いかがでしたでしょうか。
ごくごく単純なプロパティばかりですが、WPF のほぼすべてに共通して使われるものばかりですので、これらの基本を理解し前回のレイアウトと併せて使うことで、様々なレイアウトを構成することが可能となります。
次回は、やはり様々なオブジェクトで共通して使われるイベント処理を取り上げます。


著者情報

坂本 龍介後藤 雄介
株式会社アゼスト 株式会社アゼスト

アニメーションやユーザー インターフェイスのデザインなどを経て、各プロジェクトにおけるユーザー エクスペリエンス デザインやインフォメーション アーキテクトを担当する一方、Flash Media Server 2 などによる映像のストリーミング配信を利用したサービスの企画や開発を得意とする。
趣味はランニングと自転車で、健康的な開発者生活を送っている (?)

WPF アプリケーションを作る クッキングガイドのトップへ戻る WPF アプリケーションを作る クッキング ガイドのトップへ戻る

ページのトップへ ページのトップへ