VisualStateManager その1

Beta 1では単純にControlTemplate内のStoryboardのキー名称が規定されていただけだったため、カスタムのStateを作成するための枠組みは用意されていませんでした。Beta 2ではVisualStateManagerが導入されたため、簡単にカスタムのStateを作成することが可能になっています。ControlTemplate内でしか使用できないというわけではないので、わざわざカスタムコントロールを作る必要もありません。


VisualStateやVisualTransitionは、Expression Blend 2.5 June 2008 Preview(以下Blend)を使って簡単に作成、編集することができます。以下に、Blendを使ったカスタムのVisualStateの作成方法を説明します。


1.BlendでSilverlight 2 Applicationを新規に作成し、適当にButtonを1つ配置します。



2.[Interaction]パネルにある[States]で[Add State Group]ボタンを押し、任意の名前(ここではCustomとする)のVisualStateGroupを作成します。



3.作成したVisualStateGroupの右側にある[Add State]ボタンを押し、任意の名前(ここではClickedとする)のVisualStateを作成します。



4.この状態で既にStateのストーリーボードを編集する状態になっているので、[Objects and Timeline]部分の右側にある[Show Timeline]ボタンを押し、タイムラインを表示させます。



5.通常のストーリーボードの作成と同様の操作を行い、Stateとして変化させるアニメーションを作成します(ここではRenderTransformを使って単純にButtonコントロールを90度回転させるものとする)。


6.Stateの編集モードから通常のモードに戻るには、[Interaction]パネルにある[States]で[Base]という部分をクリックします。


7.Buttonコントロールを選択した状態で、画面右側の[Properties]パネル上部にある[Events]ボタンを押してButtonコントロールのイベント一覧表示させ、Clickイベント部分をダブルクリックしイベントハンドラを自動生成させます。



8.自動的にVisual Studioが起動してClickイベントのハンドラが表示されるはずなので、そこに下記のようなコードを記述します。


Visual Basic

Private Sub button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    VisualStateManager.GoToState(Me, "Clicked", False)
End Sub


このような手順でButtonコントロールのクリック時のカスタムStateを作成することができます。Blendを使うと非常に簡単です。
ちなみにBlendで自動生成されたXAMLは下記のようになっています。


XAML
<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
    x:Class="SilverlightApplication1.Page"
    Width="300" Height="300" FontSize="36">
 
    <Grid x:Name="LayoutRoot" Background="White" >
        <vsm:VisualStateManager.VisualStateGroups>
            <vsm:VisualStateGroup x:Name="Custom">
                <vsm:VisualState x:Name="Clicked">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                      Storyboard.TargetName="button"
                      Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="90"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </vsm:VisualState>
            </vsm:VisualStateGroup>
        </vsm:VisualStateManager.VisualStateGroups>
        <Button HorizontalAlignment="Stretch" Margin="60,110,60,110" VerticalAlignment="Stretch"
       Content="Button" RenderTransformOrigin="0.5,0.5" x:Name="button" Click="button_Click">
            <Button.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Button.RenderTransform>
        </Button>
    </Grid>
</UserControl>