1

I have a simple Border element in my view with a child TextBlock that is bound to a string that represents the status of a process in my application.

I am trying to animate this border so that it slides in to view from off-screen when the string that the TextBlock is bound to is modified.

Here is what I have so far:

<Border>
    <Border.Triggers>
        <EventTrigger RoutedEvent="Binding.TargetUpdated">
            <BeginStoryboard>
                <Storyboard>
                    <ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,-100,0,0" To="0,0,0,0" DecelerationRatio=".9" Duration="0:0:1" />
                    <ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,0,0,0" To="0,-100,0,0" AccelerationRatio=".9" BeginTime="0:0:5" Duration="0:0:1" />
                </Storyboard>
            </BeginStoryBoard>
        </EventTrigger>
    </Border.Triggers>
    <TextBlock Text="{Binding StatusText, Mode=OneWay, NotifyOnTargetUpdated=True}"></TextBlock>
</Border>

This works as intended but there are two problems that I do not know how to solve:

  1. The animation starts over whenever the text changes I don't want this. What I DO want is for the 5 second wait before it slides away to be restarted instead. So if the text is being constantly updated then the panel should stay still until its been more than 5 seconds since the last update then slide back up.
  2. When the application starts the animation plays immediately. I'm guessing since the initial binding counts as an update. How can I stop this from happening?
Kyle V.
  • 4,752
  • 9
  • 47
  • 81

1 Answers1

0

Considering that your data is in the ViewModel then, for problem 1 I would suggest to use a DispatcherTimer that will be restarted every time StatusText changes (you should use INotifyPropertyChanged for this). Set the DispatcherTimer.Interval to 5000 milliseconds and when it Ticks then begin the animation to slide the border outside the screen.

The problem now is since you are using MVVM the only way I know to apply animations is quite complex.

So to apply the animation manually (not from XAML, but from the ViewModel) I would suggest to create a custom control class that inherits from Border, then create an instance of the custom control class in XAML and finally trigger the "slide off the screen" animation from withing the custom control class.

To trigger the animation (located in the custom control) from the ViewModel you could have a DependencyProperty of type bool inside the custom control class that will trigger the animation when is set to true (right after the animation is started change the value of the dependency property back to false so that it can be triggered again later by changing the value to true again). It is very important that this binding that will trigger the animation uses TowWay mode so that the property in the ViewModel is also set back to false when the animation is started. So technically the bool property in the View Model will work as a switch that will automatically turn off right after you flip it (similar to the buttons and levers in Minecraft).

To solver problem 2 just keep another bool variable as flag to avoid triggering the animation when StatusText is changed for the first time.

P.S: I know that the solution to problem 1 is complex but so far is the only way I have found to trigger animations from the ViewModel without breaking MVVM.

Agustin0987
  • 581
  • 6
  • 15