■ XAML を使用したボタンの作成 ■
此のチュートリアルでは、Windows Presentation Foundation(WPF)アプリケーションで使用するア ニメーションボタンの作成方法に付いて説明する。此のチュートリアルでは、カスタマイズされたボタ ンリソースを作成するのにスタイルとテンプレートを使用する。此れに依り、コードを再利用したり、
ボタンロジックをボタン宣言から分離したり出来る様に成る。此のチュートリアルは総て Extensible
Application Markup Language(XAML)で記述されて居る。
※ 此のチュートリアルでは、Extensible Application Markup Language(XAML)を Microsoft Visual Studio に入力するか、コピーと貼り付けを行う事でアプリケーションを作成する手順に付いて説明 する。同じアプリケーションをデザインツール(Microsoft Expression Blend)を使用して作成する 方法の詳細に付いては、「チュートリアル : Microsoft Expression Blend を使用してボタンを作成す る」を参照され度い。 次の図は、完成したボタンの外観を示して居る。 ■ 基本ボタンの作成 先ず、新しいプロジェクトを作成し、ウィンドウにボタンを幾つか追加する。 新しいWPF プロジェクトを作成し、ウィンドウにボタンを追加するには 1.Visual Studio を起動する。 2.新しいWPF プロジェクトの作成:[ファイル] メニューの [新規] をポイントし、[プロジェクト] を クリックする。[WPF アプリケーション] テンプレートを選択し、プロジェクトに AnimatedButton と謂う名前を付ける。此れで、アプリケーションのスケルトンが作成される。
W
WP
PF
F
チュ
チ
ュー
ート
トリ
リア
アル
ル
3.既定の基本ボタンの追加:此のチュートリアルで必要と成るファイルは、総てテンプレートに用意 されて居る。ソリューションエクスプローラで、MainWindow.xaml をダブルクリックして開く。 MainWindow.xaml には、既定で Grid 要素が有る。Grid 要素を削除し、次の強調表示されたコー ドを Window1.xaml に入力するかコピーして貼り付けて、Extensible Application Markup Language(XAML)ページにボタンを幾つか追加する。
XAML
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AnimatedButton" Height="300" Width="300" Background="Black">
<!-- Buttons arranged vertically inside a StackPanel. --> <StackPanel HorizontalAlignment="Left"> <Button>Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button> </StackPanel> </Window> F5 キーを押してアプリケーションを実行する。次の図の様なボタンのセットが表示される。 基本ボタンを作成したので、MainWindow.xaml ファイルに対する作業は終わりで有る。此れ以降は、 ボタンのスタイルとテンプレートを定義するApplication.xaml ファイルを中心に説明する。 ■ 基本プロパティの設定 次に、此等のボタンに付いて、外観とレイアウトをコントロールする為のプロパティを幾つか設定する。
義するリソースを使用する。アプリケーションリソースは Web ページ用の外部カスケードスタイルシ ート(CSS)と概念的には似て居るが、此のチュートリアルを通じて説明される様に、リソースの方が カスケードスタイルシート(CSS)依り遥かに強力で有る。リソースの詳細に付いては、「XAML リソ ース」を参照され度い。 ボタンの基本プロパティを設定する為のスタイルを使用するには 1.Application.Resources ブロックの定義:Application.xaml を開き、次の強調表示されたマークア ップが含まれて居ない場合は追加する。 XAML <Application x:Class="Application" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <!-- アプリケーション全体のリソースを此処で定義する --> </Application.Resources> </Application> リソースのスコープは、リソースを定義する場所で決定される。Application.xaml ファイルの Application.Resoureses で定義されたリソースは、アプリケーションの何処ででも使用出来る。リ ソースのスコープの定義の詳細に付いては、「XAML リソース」を参照され度い。 2.スタイルの作成と、基本プロパティ値の定義:次のマークアップをApplication.Resources ブロッ クに追加する。此のマークアップは、アプリケーションに含まれる総てのボタンに適用されるStyle を作成する。此のスタイルに依り、ボタンのWidth は 90 に設定され、Margin は 10 に設定される。 XAML <Application.Resources> <Style TargetType="Button">
<Setter Property="Width" Value="90" /> <Setter Property="Margin" Value="10" /> </Style> </Application.Resources> TargetType プロパティは、Button 型の総てのオブジェクトに適用されるスタイルを指定する。各 Setter は Style に異なるプロパティ値を設定する。従って、此の時点では、アプリケーションに含 まれる総てのボタンの幅は90 で、余白は 10 で有る。F5 キーを押してアプリケーションを実行す ると、次の様なウィンドウが表示される。
スタイルを使用すると、他にも様々な事が出来る。例えば、対象オブジェクトを微調整する方法が 各種用意されて居る他、複雑なプロパティ値を指定したり、或るスタイルを他のスタイルの入力と して使用したりする事も出来る。詳細に付いては、「スタイルとテンプレート」を参照され度い。 3.スタイルのプロパティ値のリソースへの設定:リソースを使用する事で、一般的に定義されるオブ ジェクトや値を簡単に再利用出来る。複雑な値をリソースを使用して定義する事は、コードをモジ ュール化するのに大変便利で有る。次の強調表示されたマークアップをApplication.xaml に追加す る。 XAML <Application.Resources> <LinearGradientBrush x:Key="GrayBlueGradientBrush" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="DarkGray" Offset="0" /> <GradientStop Color="#CCCCFF" Offset="0.5" /> <GradientStop Color="DarkGray" Offset="1" /> </LinearGradientBrush>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="10" /> </Style> </Application.Resources> Application.Resources ブロックの直下に、"GrayBlueGradientBrush" と謂うリソースが作成され て居る。此のリソースは、水平方向のグラデーションを定義する。此のリソースは、Background プロパティのボタンスタイルのSetter の内部から等、アプリケーションの何処からでもプロパティ 値として使用出来る。此れで、総てのボタンが此のグラデーションのBackground プロパティを持 つ様に成った。
F5 キーを押してアプリケーションを実行する。結果は次の様に成る。 ■ ボタンの外観を定義するテンプレートの作成 此処では、ボタンの外観(プレゼンテーション)カスタマイズするテンプレートを作成する。ボタンプ レゼンテーションは、四角形等のコンポーネントを含む幾つかのオブジェクトで構成され、ボタンに固 有の外観を指定する。 此れ迄、アプリケーションに於けるボタンの外観のコントロールは、ボタンのプロパティを変更する事 に制限されて居た。ボタンの外観を更に大きく変更するには何うすれば良いか。テンプレートを使用す ると、オブジェクトのプレゼンテーションを強力にコントロール出来る。テンプレートはスタイル内で 使用出来るので、スタイルが適用される総てのオブジェクト(此のチュートリアルではボタン)にテン プレートを適用出来る。 ボタンの外観を定義するテンプレートを使用するには 1.テンプレートのセットアップ:Button 等のコントロールには Template プロパティが有るので、テ ンプレートのプロパティ値は、Style で Setter を使用して設定した他のプロパティと同じ様にして 定義出来る。次の強調表示されたマークアップをボタンスタイルに追加する。 XAML <Application.Resources> <LinearGradientBrush x:Key="GrayBlueGradientBrush" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="DarkGray" Offset="0" /> <GradientStop Color="#CCCCFF" Offset="0.5" /> <GradientStop Color="DarkGray" Offset="1" /> </LinearGradientBrush>
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="10" /> <Setter Property="Template">
<Setter.Value>
<!-- The button template is defined here. --> </Setter.Value> </Setter> </Style> </Application.Resources> 2.ボタンプレゼンテーションの変更:此の時点でテンプレートを定義する必要が有る。次の強調表示 されたマークアップを追加する。此のマークアップは、角が丸い 2 つの Rectangle 要素を指定し、
続いてDockPanel を指定する。DockPanel はボタンの ContentPresenter をホストする為に使用 される。ContentPresenter にはボタンのコンテンツが表示される。此のチュートリアルでは、コ ンテンツはテキスト("Button 1"、"Button 2"、"Button 3")で有る。テンプレートコンポーネン ト(四角形とDockPanel)は総て Grid 内部にレイアウトされる。
XAML
<Setter.Value>
<ControlTemplate TargetType="Button"> <Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}" ClipToBounds="True">
<!-- Outer Rectangle with rounded corners. --> <Rectangle x:Name="outerRectangle"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Stroke="{TemplateBinding Background}"
RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" />
<!-- Inner Rectangle with rounded corners. --> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" />
<!-- Present Content (text) of the button. -->
<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel> </Grid> </ControlTemplate> </Setter.Value>
F5 キーを押してアプリケーションを実行する。結果は次の様に成る。 3.テンプレートへのグラス効果の追加:次に、グラスを追加する。先ず、グラスグラデーション効果 を作成するリソースを幾つか作成する。此等のグラデーションリソースを Application.Resources ブロック内の何処か(先頭部分が良い)に追加する。 XAML <Application.Resources> <GradientStopCollection x:Key="MyGlassGradientStopsResource"> <GradientStop Color="WhiteSmoke" Offset="0.2" />
<GradientStop Color="Transparent" Offset="0.4" /> <GradientStop Color="WhiteSmoke" Offset="0.5" /> <GradientStop Color="Transparent" Offset="0.75" /> <GradientStop Color="WhiteSmoke" Offset="0.9" /> <GradientStop Color="Transparent" Offset="1" /> </GradientStopCollection>
<LinearGradientBrush x:Key="MyGlassBrushResource" StartPoint="0,0" EndPoint="1,1" Opacity="0.75"
GradientStops="{StaticResource MyGlassGradientStopsResource}" /> <!-- スタイルや他のリソースは此処より下に記述 --> 此等のリソースは、ボタンテンプレートのGrid に挿入する四角形の Fill として使用される。次の 強調表示されたマークアップをテンプレートに追加する。 XAML <Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True">
<!-- Outer Rectangle with rounded corners. -->
<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" />
<!-- Inner Rectangle with rounded corners. -->
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" />
<!-- Glass Rectangle -->
<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0" Fill="{StaticResource MyGlassBrushResource}"
RenderTransformOrigin="0.5,0.5"> <Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush>
</Rectangle.Stroke>
<!-- These transforms have no effect as they are declared here.
The reason the transforms are included is to be targets
for animation (see later). -->
<Rectangle.RenderTransform> <TransformGroup> <ScaleTransform /> <RotateTransform /> </TransformGroup> </Rectangle.RenderTransform>
<!-- A BevelBitmapEffect is applied to give the button a "Beveled" look. -->
<Rectangle.BitmapEffect> <BevelBitmapEffect /> </Rectangle.BitmapEffect> </Rectangle>
<!-- Present Text of the button. -->
<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter" Margin="20"
Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel>
</Grid>
</ControlTemplate> </Setter.Value>
"glassCube" の x:Name プロパティを持つ四角形の Opacity は 0 なので、此のサンプルを実行する と、グラス四角形は最前面にオーバーレイ表示されない。此れは、ユーザーがボタンを使用して対 話操作を行う場合に付いて、後でトリガーをテンプレートに追加するからで有る。但し、Opacity 値を1 に変更してアプリケーションを実行すると、ボタンの外観を直ぐに確認出来る。次の図を参 照され度い。次の手順に進む前に、Opacity を 0 に戻す。 ■ ボタンの対話機能の作成 此処では、マウスポインターをボタンに合わせてクリックする等のユーザーアクションに対応して、プ ロパティ値を変更してアニメーションを実行するプロパティトリガー、及び、イベントトリガーを作成 する。 対話機能(マウスオーバー、マウスリーブ、クリック等)を追加する簡単な方法は、テンプレートやスタ イルの内部にトリガーを定義する事で有る。Trigger を作成するには、ボタンの IsMouseOver プロパテ ィがtrue に等しいと謂ったプロパティ "条件" を作成する。次に、トリガー条件が true に成った時に 実行されるsetter(アクション)定義する。 ボタンの対話機能を作成するには 1.テンプレートトリガーの追加:次の強調表示されたマークアップをテンプレートに追加する。 XAML <Setter.Value>
<ControlTemplate TargetType="{x:Type Button}"> <Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}" ClipToBounds="True">
<!-- Outer Rectangle with rounded corners. -->
<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" />
<!-- Inner Rectangle with rounded corners. -->
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent"
StrokeThickness="20"
Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" />
<!-- Glass Rectangle -->
<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0" Fill="{StaticResource MyGlassBrushResource}"
RenderTransformOrigin="0.5,0.5"> <Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush>
</Rectangle.Stroke>
<!-- These transforms have no effect as they are declared here. The reason the transforms are included is to be targets for animation (see later). -->
<Rectangle.RenderTransform> <TransformGroup> <ScaleTransform /> <RotateTransform /> </TransformGroup> </Rectangle.RenderTransform>
<!-- A BevelBitmapEffect is applied to give the button a "Beveled" look. --> <Rectangle.BitmapEffect>
<BevelBitmapEffect /> </Rectangle.BitmapEffect> </Rectangle>
<!-- Present Text of the button. -->
<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter" Margin="20"
Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel>
</Grid>
<ControlTemplate.Triggers>
<!-- Set action triggers for the buttons and define
what the button does in response to those triggers. -->
</ControlTemplate.Triggers> </ControlTemplate>
2.プロパティトリガーの追加:次の強調表示されたマークアップを ControlTemplate.Triggers ブロ ックに追加する。
XAML
<ControlTemplate.Triggers>
<!-- Set properties when mouse pointer is over the button. -->
<Trigger Property="IsMouseOver" Value="True">
<!-- Below are three property settings that occur when the
condition is met (user mouses over button). -->
<!-- Change the color of the outer rectangle when user mouses over it. --> <Setter Property ="Rectangle.Stroke" TargetName="outerRectangle"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<!-- Sets the glass opacity to 1, therefore, the
glass "appears" when user mouses over it. -->
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
<!-- Makes the text slightly blurry as though you
were looking at it through blurry glass. -->
<Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter"> <Setter.Value> <BlurBitmapEffect Radius="1" /> </Setter.Value> </Setter> </Trigger> <ControlTemplate.Triggers/> F5 キーを押してアプリケーションを実行し、マウスポインタをボタンに合わせた時の効果を確認 する。 3.フォーカストリガーの追加:次に、ボタンにフォーカスが有る場合(ユーザーがクリックした後等) を処理する同様のsetter を追加する。 XAML <ControlTemplate.Triggers>
<!-- Set properties when mouse pointer is over the button. --> <Trigger Property="IsMouseOver" Value="True">
<!-- Below are three property settings that occur when the condition is met (user mouses over button). -->
<!-- Change the color of the outer rectangle when user mouses over it. --> <Setter Property ="Rectangle.Stroke" TargetName="outerRectangle"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<!-- Sets the glass opacity to 1, therefore, the glass "appears" when user mouses over it. --> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
<Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter"> <Setter.Value> <BlurBitmapEffect Radius="1" /> </Setter.Value> </Setter> </Trigger>
<!-- Set properties when button has focus. -->
<Trigger Property="IsFocused" Value="true">
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> <Setter Property="Rectangle.Stroke" TargetName="outerRectangle"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" /> </Trigger> </ControlTemplate.Triggers> F5 キーを押してアプリケーションを実行し、孰れかのボタンをクリックする。クリックされた後 でもフォーカスが有るので、ボタンは強調表示された儘に成る。別のボタンをクリックすると、新 しいボタンにフォーカスが移り、其れ迄のボタンはフォーカスを失う。 4.MouseEnter と MouseLeave へのアニメーションの追加:次に、トリガーにアニメーションを追加 する。次のマークアップをControlTemplate.Triggers ブロックの中に追加する。 XAML
<!-- Animations that start when mouse enters and leaves button. -->
<EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions>
<BeginStoryboard Name="mouseEnterBeginStoryboard"> <Storyboard>
<!-- This animation makes the glass rectangle shrink in the X direction. -->
<DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" By="-0.1" Duration="0:0:0.5" />
<!-- This animation makes the glass rectangle shrink in the Y direction. -->
<DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" By="-0.1" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions>
<!-- Stopping the storyboard sets all animated properties back to default. -->
<StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard" /> </EventTrigger.Actions>
グラス四角形は、マウスポインタをボタンに合わせると小さく成り、ポインターが離れると標準サ イズに戻る。
ポインターをボタンに合わせた時(MouseEnter イベントが発生した時)にトリガーされるアニメ
ーションは2 つ有る。此等のアニメーションは、グラス四角形を夫々X 軸及び Y 軸方向に縮小する。
DoubleAnimation 要素のプロパティは、Duration と By で有る。Duration はアニメーションが 0.5 秒間発生する様に指定し、By はグラスが 10% 縮小される様に指定する。 2 番目のイベントトリガー(MouseLeave)は、単純に最初のイベントを停止する。Storyboard を 停止すると、アニメーション化された総てのプロパティが既定値に戻る。従って、ユーザーがポイ ンターをボタンから離すと、ボタンはマウスポインタをボタンに合わせる前の状態に戻る。アニメ ーションの詳細に付いては、「アニメーションの概要」を参照され度い。 5.ボタンがクリックされた時のアニメーションの追加:最後の手順は、ユーザーがボタンをクリック した時のトリガーの追加で有る。次のマークアップを ControlTemplate.Triggers ブロックの中に 追加する。 XAML
<!-- Animation fires when button is clicked, causing glass to spin. -->
<EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" By="360" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> F5 キーを押してアプリケーションを実行し、孰れかのボタンをクリックする。ボタンをクリック すると、グラス四角形が回転する。 http://msdn.microsoft.com/ja-jp/library/bb613545(v=vs.110).aspx http://msdn.microsoft.com/ja-jp/library/ee649089(v=vs.110).aspx