N
N
Nikita Tratorov2012-10-20 20:57:47
.NET
Nikita Tratorov, 2012-10-20 20:57:47

WPF: Add animation via inline style on element?

Question for the connoisseurs.
I have expander.
I added a style to it, in which I defined an animation for collapsing / expanding content (Content):

<Expander>
...
<Expander.Style>
  <Style>
    <Setter Property="Expander.BorderBrush" Value="LightBlue" />
    <Setter Property="Expander.BorderThickness" Value="1" />
    <Style.Triggers>
      <Trigger Property="Expander.IsExpanded" Value="True">
        <Trigger.EnterActions>
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation From="0" Duration="0:0:0.2" Storyboard.TargetProperty="Content.Height" />
            </Storyboard>
          </BeginStoryboard>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetProperty="Content.Height" />
            </Storyboard>
          </BeginStoryboard>
        </Trigger.ExitActions>
      </Trigger>
    </Style.Triggers>
  </Style>
</Expander.Style>
</Expander>

The content expands smoothly.
Now about the problems:
1. The content does not smoothly collapse.
2. I want the arrow on the button to rotate 180 degrees, according to the example:
<ControlTemplate.Triggers>
    <!-- Animate arrow when toggled-->
    <Trigger Property="IsChecked"
             Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="Arrow"
                         Storyboard.TargetProperty=
                           "(Path.RenderTransform).(RotateTransform.Angle)"
                         To="180"
                         Duration="0:0:0.4"/>
                </Storyboard>
            </BeginStoryboard>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="Arrow"
                         Storyboard.TargetProperty=
                           "(Path.RenderTransform).(RotateTransform.Angle)"
                         To="0"
                         Duration="0:0:0.4"/>
                </Storyboard>
            </BeginStoryboard>
        </Trigger.ExitActions>
    </Trigger>
</ControlTemplate.Triggers>

those. change the original code to this:
<Expander.Style>
    <Style>
        <Setter Property="Expander.BorderBrush" Value="LightBlue" />
        <Setter Property="Expander.BorderThickness" Value="1" />
        <Style.Triggers>
            <Trigger Property="Expander.IsExpanded" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation From="0" Duration="0:0:0.2" Storyboard.TargetProperty="Content.Height" />
                            <DoubleAnimation Storyboard.TargetName="Arrow" Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)" To="180" Duration="0:0:0.4"/>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetProperty="Content.Height" />
                            <DoubleAnimation Storyboard.TargetName="Arrow" Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)" To="0" Duration="0:0:0.4"/>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.ExitActions>
            </Trigger>
        </Style.Triggers>
    </Style>
</Expander.Style>

But, as you understand. This code doesn't work. Please tell me what is wrong here?
Inspired by this article .

Answer the question

In order to leave comments, you need to log in

3 answer(s)
P
Paulskit, 2012-10-22
@NikitaTratorov

Better to do it right.
1) Your approach with Content.Height is wrong. If Height is not set, that is, it is equal to NaN, we get a RuntimeException.
2) Instead of writing the style inside the element, store it in Resources for the given window/page.
3) Redefine ContentTemplate to make the animation work for all cases.
Now about why it doesn't work.
Initially, everything works like this. The Visibility property of our ContentPresenter is set to Collapsed. The expansion is performed by the following trigger.

<Trigger Property="IsExpanded" Value="true">
   <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>

In order to correct the situation, let's rewrite the ControlTemplate a bit.
Let's first remove the Visibility property.
After that, add the following block inside:
<ContentPresenter.LayoutTransform>
   <ScaleTransform ScaleX="1" ScaleY="0"/>
</ContentPresenter.LayoutTransform>

And finally, replace the above trigger with these:
<EventTrigger RoutedEvent="Expander.Expanded">
   <BeginStoryboard>
      <Storyboard Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="LayoutTransform.ScaleY">
          <DoubleAnimation To="1" Duration="0:0:0.2"/>
      </Storyboard>
   </BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Expander.Collapsed">
   <BeginStoryboard>
      <Storyboard Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="LayoutTransform.ScaleY">
          <DoubleAnimation To="0" Duration="0:0:0.2"/>
      </Storyboard>
   </BeginStoryboard>
</EventTrigger>

Example:
pastebin.com/FmGAVbA5

R
renny, 2012-10-20
@renny

1) You have created a trigger only for a reversal, that's why it collapses without animation.
Create a trigger for
and and you will be happy
2) create an empty transformation at the “arrow” (those without values) and everything will work <
Arrow RenderTransformOrigin=" 0.5,0.5 " > /> <TranslateTransform /> </Arrow .RenderTransform> </Arrow >

N
Nikita Tratorov, 2012-10-21
@NikitaTratorov

Does anyone have any thoughts?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question