Storyboard flicker between remove and begin

598 views Asked by At

I have these two animations defined in UserControl.Resources:

<Storyboard x:Key="pStatusExpand"
            AccelerationRatio=".4"
            DecelerationRatio=".4">
    <DoubleAnimation Storyboard.TargetProperty="Tag"
                        Duration="0:0:0.6" 
                        From="0" To="1"
                        />
</Storyboard>
<Storyboard x:Key="pStatusHide"
            AccelerationRatio=".4"
            DecelerationRatio=".4">
    <DoubleAnimation Storyboard.TargetProperty="Tag"
                        Duration="0:0:0.6" 
                        From="1" To="0"
                        BeginTime="0:0:0.5"
                        />
</Storyboard>

I animate them in the grid they belong to with the following triggers:

<Grid.Style>
    <Style TargetType="{x:Type Grid}">
        <Style.Triggers>
            <DataTrigger Value="true">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource MaxConverter}">
                        <Binding ElementName="self" Path="Items.Count" />
                        <Binding ElementName="self" Path="MaxCountItems" />
                    </MultiBinding>
                </DataTrigger.Binding>
                <DataTrigger.EnterActions>
                    <RemoveStoryboard BeginStoryboardName="Expand" />
                    <BeginStoryboard Name="Hide" Storyboard="{StaticResource pStatusHide}" />
                </DataTrigger.EnterActions>
            </DataTrigger>
            <DataTrigger Binding="{Binding ElementName=self, Path=Items.Count}" Value="0">
                <DataTrigger.EnterActions>
                    <RemoveStoryboard BeginStoryboardName="Hide" />
                    <BeginStoryboard Name="Expand" Storyboard="{StaticResource pStatusExpand}" />
                </DataTrigger.EnterActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Grid.Style>

The animations adjust the Grid's Height with:

<Grid.Height>
    <MultiBinding Converter="{StaticResource MultiplyConverter}">
        <Binding ElementName="self" Path="StatusHeight" />
        <Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
    </MultiBinding>
</Grid.Height>

The problem I'm having is that between the RemoveStoryBoard named Expand the height is set to 0 from its animated end value of ~25 and the BeginStoryBoard named Hide, when it starts sets the height back the full amount to begin animating it down to 0.

To rephrase that:

  1. The Expand animation fires because Items.Count equals 0. It grows/animates the grid's Height to 25.
  2. The loading continues until...
  3. Items.Count now equals MaxCountItems which fires the second trigger (for hiding)
  4. The Expand animation is removed (causing the flicker), but if it isn't removed - the Hide animation doesn't do anything (or appears not to).

The flicker appears to be, the grid's height is briefly set to 0 when Expand is removed and Hide begins.

The triggers work, but a few notes for those that care though in my opinion are irrelevant to the question at hand:

  • self is the UserControl the grid resides in
  • StatusHeight is a dependency property that defaults to a certain height.
  • MaxConverter checks to see if Items.Count >= MaxCountItems
  • MultiplyConverter multiplies the Tag value with the StatusHeight, so I can bind the animation to a height and avoid freeze issues. Note, the animation is from 0 to 1 and 1 to 0.

Ideas to avoid the flicker?

1

There are 1 answers

1
Sheridan On BEST ANSWER

I have two possible suggestions for you, although they are just that... suggestions. The first relates to the BeginTime that you have set for your pStatusHide Storyboard... if you set that to 0:0:0 then it should start without delay... maybe that half second delay is when you see the flicker.

The other suggestion is to replace your RemoveStoryboard with a StopStoryboard, or even beter, a PauseStoryboard. That way, the last value would be held, instead of reverting (momentarily) to 0.