Awaitable storyboard in WPF

Normally when a storyboard is running, setting the FillBehavior (Learn more about FillBehavior) to HoldEnd is risk. Because for a dependency property, storyboard is considered to have highest priority of setting the value. So once storyboard is done, user cannot change its value locally. So users prefer the set the FillBehavior to Stop and change the target value once storyboard is done. So there must be always a need to do something once animation is done. Fortunately, storyboard provided an event called Completed where we can write our own logic.

But once async and await released to get rid off these callback approach, why can’t we make our storyboard an awaitable one. Let the storyboard Begin method wait until the animation completed, before it executed the next line.

        public static Task BeginAsync(this Storyboard timeline)
        {
            TaskCompletionSource<object> source = new TaskCompletionSource<object>();
            timeline.Completed += delegate
            {
                source.SetResult(null);
            };
            timeline.Begin();
            return source.Task;
        }

This is how we will be using it in our application,

        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Storyboard animation = (Storyboard)this.Resources["HideAnimation"];
            if (animation != null)
            {
                await animation.BeginAsync();
                MessageBox.Show("Animation completed");
            }
        }

Note : It is always not recommended to use async void except UI event handlers.

Leave a comment

Up ↑