BaconographyWP8.Common.ReorderListBox.AnimateRearrangeInternal C# (CSharp) Method

AnimateRearrangeInternal() private method

Orchestrates the rearrange animation process.
private AnimateRearrangeInternal ( System.Action rearrangeAction, Duration animationDuration ) : void
rearrangeAction System.Action
animationDuration Duration
return void
        private void AnimateRearrangeInternal(Action rearrangeAction, Duration animationDuration)
        {
            // Find the indices of items in the view. Animations are optimzed to only include what is visible.
            int viewFirstIndex, viewLastIndex;
            this.GetViewIndexRange(true, out viewFirstIndex, out viewLastIndex);

            // Collect information about items and their positions before any changes are made.
            RearrangeItemInfo[] rearrangeMap = this.BuildRearrangeMap(viewFirstIndex, viewLastIndex);

            // Call the rearrange action callback which actually makes the changes to the source list.
            // Assuming the source list is properly bound, the base class will pick up the changes.
            rearrangeAction();

            this.rearrangeCanvas.Visibility = Visibility.Visible;

            // Update the layout (positions of all items) based on the changes that were just made.
            this.UpdateLayout();

            // Find the NEW last-index in view, which may have changed if the items are not constant heights
            // or if the view includes the end of the list.
            viewLastIndex = this.FindViewLastIndex(viewFirstIndex);

            // Collect information about the NEW items and their NEW positions, linking up to information
            // about items which existed before.
            RearrangeItemInfo[] rearrangeMap2 = this.BuildRearrangeMap2(rearrangeMap,
                viewFirstIndex, viewLastIndex);

            // Find all the movements that need to be animated.
            IEnumerable<RearrangeItemInfo> movesWithinView = rearrangeMap
                .Where(rii => !Double.IsNaN(rii.FromY) && !Double.IsNaN(rii.ToY));
            IEnumerable<RearrangeItemInfo> movesOutOfView = rearrangeMap
                .Where(rii => !Double.IsNaN(rii.FromY) && Double.IsNaN(rii.ToY));
            IEnumerable<RearrangeItemInfo> movesInToView = rearrangeMap2
                .Where(rii => Double.IsNaN(rii.FromY) && !Double.IsNaN(rii.ToY));
            IEnumerable<RearrangeItemInfo> visibleMoves =
                movesWithinView.Concat(movesOutOfView).Concat(movesInToView);

            // Set a clip rect so the animations don't go outside the listbox.
            this.rearrangeCanvas.Clip = new RectangleGeometry() { Rect = new Rect(new Point(0, 0), this.rearrangeCanvas.RenderSize) };

            // Create the animation storyboard.
            Storyboard rearrangeStoryboard = this.CreateRearrangeStoryboard(visibleMoves, animationDuration);
            if (rearrangeStoryboard.Children.Count > 0)
            {
                // The storyboard uses an overlay canvas with item snapshots.
                // While that is playing, hide the real items.
                this.scrollViewer.Visibility = Visibility.Collapsed;

                rearrangeStoryboard.Completed += delegate
                {
                    rearrangeStoryboard.Stop();
                    this.rearrangeCanvas.Children.Clear();
                    this.rearrangeCanvas.Visibility = Visibility.Collapsed;
                    this.scrollViewer.Visibility = Visibility.Visible;

                    this.AnimateNextRearrange();
                };

                this.Dispatcher.BeginInvoke(() => rearrangeStoryboard.Begin());
            }
            else
            {
                this.rearrangeCanvas.Visibility = Visibility.Collapsed;
                this.AnimateNextRearrange();
            }
        }