Visual State Manager

WPFではイベントトリガーやプロパティトリガーやデータトリガーなどのTriggerを使えば、コードを書かなくても、以下のようにXAML内でVisualオブジェクトやUIコントロールのスタイルを変化させることができました。

<Style.Triggers>

   <Trigger Property="IsMouseOver" Value="True">

      <Trigger.Setters>

         <Setter Property="Width" Value="200" />

      </Trigger.Setters>

   </Trigger>

</Style.Triggers>

Silverlight 2ではTriggerはサポートされていません。それに代わってVisual State Managerが導入されました。Visual State Managerはその名の通りVisual の状態管理を行い、それぞれの状態に応じたアニメーションをテンプレートとして定義することができます。

<ControlTemplate TargetType="Button">

<Border x:Name="RootElement"
CornerRadius="4" BorderThickness="4">

<Border.RenderTransform>

<ScaleTransform/>

</Border.RenderTransform>

<

VisualStateManager.VisualStateGroups>

    <VisualStateGroup>

      <VisualStateGroup.Transitions>    

        <VisualTransition From="Normal"

             To="MouseOver" Duration="0:0:2" />

         <VisualTransition From="MouseOver"

             To="Normal" Duration="0:0:0.2" /> 

       </VisualStateGroup.Transitions> 

       <VisualState x:Name="Normal" />

       <VisualState x:Name="MouseOver" >

         <Storyboard >

          <DoubleAnimation To="2" Duration="0:0:0"

  Storyboard.TargetName="myScale"

  Storyboard.TargetProperty="ScaleX" />

          <DoubleAnimation To="2" Duration="0:0:0"

  Storyboard.TargetName="myScale"

Storyboard.TargetProperty="ScaleY" />

         </Storyboard>  

        </VisualState>

     </VisualStateGroup>

   </VisualStateManager.VisualStateGroups>

</Border>

</ControlTemplate>

Visual State Managerについて重要なことが3点あります。1つは 、ある状態(VisualState)でのアニメーションと、ある状態から別の状態への遷移(VisualTransition)の両方が定義できることです。例えば、MouseOverするとボタンが拡大し、MouseOverの間ずっと点滅するようなアニメーションが定義できます。

もう1つは、このVisual State Managerの設定がExpression Blend 2.5に統合されていることです。非常に簡単にコントロールの状態アニメーションと遷移アニメーションが作成できます。これについてはExpression Blend 2.5 June CTPのビデオストリーミングがあるので、観てみてください。ScotGuのブログにもExpression Blendを使ったVSM Supportが紹介されています。

最後に、このVisual State Managerは現在ベータが公開されている.NET Framework 3.5 SP1にも将来の.NET Frameworkにも搭載される予定であることです。WPFとSilverlightでVisualオブジェクトやUIコントロールの共通のカスタマイズが可能になります。

ただし、制限もあります。Visual State ManagerからButtonのようなUIコンポーネントの既存の状態を基にテンプレートを作成するときは、コードを書く必要はないのですが、Controlなどから継承して状態を新しく追加する場合には、コードビハインドでイベントハンドラから明示的にVisualStateManager.GoToStateメソッドを呼び出す必要があります。これについてはAdd States to a UserControl for Silverlight 2をご覧ください。

[訂正] Visual State Manager は .NET Framewoerk 3.5 SP1ではまだサポートされていません。