W poprzedniej części było trochę o teorii VisualStateManager’a. Dziś zajmiemy się praktyką. Zobaczymy jak zamienić nieruchomy przycisk w coś bardziej ruchomego.

Zacznijmy od podstaw:

<ControlTemplate>

    <Canvas>

        <Canvas.RenderTransform>

            <ScaleTransform CenterX=”15″ CenterY=”15″ ScaleX=”1″ ScaleY=”1″

                          x:Name=”scaleTransform”/>

        Canvas.RenderTransform>

        <Ellipse Stroke=”Black” StrokeThickness=”4″

            Fill=”Orange” Width=”30″ Height=”30″ />

        <Line Stroke=”Black” StrokeThickness=”4″

                  X1=”9″ Y1=”9″ X2=”21″ Y2=”21″ />

        <Line Stroke=”Black” StrokeThickness=”4″

                  X1=”9″ Y1=”21″ X2=”21″ Y2=”9″ />

 

        <VisualStateManager.VisualStateGroups>

            <VisualStateGroup x:Name=”CommonStates”>

 

            VisualStateGroup>

        VisualStateManager.VisualStateGroups>

    Canvas>

ControlTemplate>

Na początek dodaliśmy transformację ScaleTransform i nadaliśmy jej nazwę. Przyda się, gdy będziemy chcieli zmienić nasz przycisk.
Kolejnym krokiem będzie dodanie jak ma wyglądać nasz przycisk w poszczególnych stanach. Na pierwszy “ogień” MouseOver

<VisualState x:Name=”MouseOver”>

    <Storyboard>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

                        To=”1.2″ Storyboard.TargetProperty=”ScaleX”/>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

                        To=”1.2″ Storyboard.TargetProperty=”ScaleY”/>

    Storyboard>

VisualState>

Prosta animacja zwiększająca przycisk do 120%. Jednak, jeśli uruchomimy taki kod to po najechaniu kursorem kontrolka pozostaje w stanie w jakim była po najechaniu kursorem. Tego co nam brakuje to zdefiniowany stan “Normal”. Uzupełnimy go zatem.

Nasz kod wygląda zatem tak:

<VisualState x:Name=”MouseOver”>

    <Storyboard>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

                        To=”1.2″ Storyboard.TargetProperty=”ScaleX”/>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

                        To=”1.2″ Storyboard.TargetProperty=”ScaleY”/>

    Storyboard>

VisualState>

<VisualState x:Name=”Normal”>

    <Storyboard>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

                        To=”1″ Storyboard.TargetProperty=”ScaleX”/>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

                        To=”1″ Storyboard.TargetProperty=”ScaleY”/>

    Storyboard>

VisualState>

Przycisk na chwilę obecną prezentuje się następująco:

Dodajmy zatem kolejne stany. Chcemy, aby przycisk “wyszarzał” gdy jest w trybie disabled.
Po pierwsze musimy dodać nazwę dla elipsy:

<Ellipse Stroke=”Black” StrokeThickness=”4″

            Fill=”Orange” Width=”30″ Height=”30″ x:Name=”ellipse” />

A następnie definiujemy zachowanie dla trybu “disabled”. Znów prosta animacja zmieniająca kolor z pomarańczowego na szary.

<VisualState x:Name=”Disabled”>

    <Storyboard>

        <ColorAnimation To=”Gray” Duration=”0:0:0.3″

                      Storyboard.TargetName=”ellipse”

                      Storyboard.TargetProperty=”(SolidColorBrush.Fill).Color”/>

    Storyboard>

VisualState>

Jednak przy takiej definicji w przypadku zmiany ze stanu Disabled do Normal, kontrolka powróci do stanu Normal, bez żadnego przejścia.

Możemy to zmienić definiując przejścia. Zdefiniujmy zatem jedno:

<VisualStateGroup.Transitions>

    <VisualTransition From=”Disabled” To=”Normal”>

        <Storyboard>

            <ColorAnimation To=”Orange” Duration=”0:0:0.3″

                      Storyboard.TargetName=”ellipse”

                      Storyboard.TargetProperty=”(SolidColorBrush.Fill).Color”/>

        Storyboard>

    VisualTransition>

VisualStateGroup.Transitions>

Dzięki temu nasza kontrolka zachowuje się następująco:

Teraz, skoro nasz przycisk poprawnie zachowuje się w stanie “normalnym” oraz “disabled” spróbujmy dodać mu trochę ruchu, gdy użytkownik klika na niego. Oczywiście przydatny będzie tu stan Pressed.

Mając za sobą to co już napisaliśmy, dodanie animacji dla trybu Pressed, będzie niezwykle proste. Zakręćmy trochę naszym przyciskiem.

Dodajemy nową transformację

<Canvas.RenderTransform>

    <TransformGroup>

        <ScaleTransform CenterX=”15″ CenterY=”15″ ScaleX=”1″ ScaleY=”1″

                      x:Name=”scaleTransform”/>

        <RotateTransform CenterX=”15″ CenterY=”15″ Angle=”0″

                        x:Name=”rotateTransform”/>

    TransformGroup>

Canvas.RenderTransform>

i używamy jej do animacji przycisku podczas naciskania przy okazji troszkę go zmniejszając:

<VisualState x:Name=”Pressed”>

    <Storyboard>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

              To=”.9″ Storyboard.TargetProperty=”ScaleX”/>

        <DoubleAnimation Storyboard.TargetName=”scaleTransform” Duration=”0:0:0.125″

              To=”.9″ Storyboard.TargetProperty=”ScaleY”/>

        <DoubleAnimation Storyboard.TargetName=”rotateTransform” Duration=”0:0:0.25″

              To=”180″ Storyboard.TargetProperty=”Angle” />

    Storyboard>

VisualState>

Przycisk prezentuje się teraz następująco:

Na koniec możemy jeszcze przycisk “odkręcić”

<VisualTransition From=”Pressed” To=”MouseOver”>

    <Storyboard>

        <DoubleAnimation Storyboard.TargetName=”rotateTransform” Duration=”0:0:0.25″

          To=”0″ Storyboard.TargetProperty=”Angle” />

    Storyboard>

VisualTransition>

<VisualTransition From=”Pressed” To=”Normal”>

    <Storyboard>

        <DoubleAnimation Storyboard.TargetName=”rotateTransform” Duration=”0:0:0.25″

          To=”0″ Storyboard.TargetProperty=”Angle” />

    Storyboard>

VisualTransition>

Aby mieć całkowicie animowany przycisk pozostaje nam jeszcze do zaimplementowania kilka stanów i przejść, ale to już pozostawiam dla każdego jako ‘zadanie domowe’. Myślę, że po tym co tu zostało pokazane nie będzie to trudne.

Pełny kod przycisku – CloseButton.xaml.