/// <summary>
 /// Begins a storyboard and waits for it to complete.
 /// </summary>
 public static async Task BeginAsync(this Storyboard storyboard)
 {
     await EventAsync.FromEvent <object>(
         eh => storyboard.Completed += eh,
         eh => storyboard.Completed -= eh,
         storyboard.Begin);
 }
        /// <summary>
        /// Scrolls to horizontal offset asynchronously.
        /// </summary>
        /// <param name="scrollViewer">The scroll viewer.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>The task that completes when scrolling is complete.</returns>
        public static async Task ScrollToHorizontalOffsetAsync(this ScrollViewer scrollViewer, double offset)
        {
            if (offset < 0)
            {
                offset = 0;
            }

            if (offset > scrollViewer.ScrollableWidth)
            {
                offset = scrollViewer.ScrollableWidth;
            }

            var currentOffset = scrollViewer.HorizontalOffset;

            // ReSharper disable CompareOfFloatsByEqualityOperator
            if (offset == currentOffset)
            {
                return;
            }

            scrollViewer.ScrollToHorizontalOffset(offset);

            if (scrollViewer.HorizontalOffset == offset)
            {
                return;
            }

            if (scrollViewer.HorizontalOffset != currentOffset)
            {
                return;
            }
            // ReSharper restore CompareOfFloatsByEqualityOperator

            await EventAsync.FromEvent <ScrollViewerViewChangedEventArgs>(
                eh => scrollViewer.ViewChanged += eh,
                eh => scrollViewer.ViewChanged -= eh);
        }
        /// <summary>
        /// Scrolls to vertical offset with animation asynchronously.
        /// </summary>
        /// <param name="scrollViewer">The scroll viewer.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>The task that completes when scrolling is complete.</returns>
        public static async Task ScrollToVerticalOffsetWithAnimationAsync(this ScrollViewer scrollViewer, double offset)
        {
            if (offset < 0)
            {
                offset = 0;
            }

            if (offset > scrollViewer.ScrollableHeight)
            {
                offset = scrollViewer.ScrollableHeight;
            }

            var currentOffset = scrollViewer.VerticalOffset;

            // ReSharper disable CompareOfFloatsByEqualityOperator
            if (offset == currentOffset)
            {
                return;
            }

            await scrollViewer.ScrollToVerticalOffsetWithAnimation(offset);

            if (scrollViewer.VerticalOffset == offset)
            {
                return;
            }

            if (scrollViewer.VerticalOffset != currentOffset)
            {
                return;
            }
            // ReSharper restore CompareOfFloatsByEqualityOperator

            await EventAsync.FromEvent <ScrollViewerViewChangedEventArgs>(
                eh => scrollViewer.ViewChanged += eh,
                eh => scrollViewer.ViewChanged -= eh);
        }