private Storyboard CreateRearrangeStoryboard(IEnumerable<RearrangeItemInfo> visibleMoves,
Duration animationDuration)
{
Storyboard storyboard = new Storyboard();
ReorderListBoxItem temporaryItemContainer = null;
foreach (RearrangeItemInfo move in visibleMoves)
{
Size itemSize = new Size(this.rearrangeCanvas.RenderSize.Width, move.Height);
ReorderListBoxItem itemContainer = null;
if (move.ToIndex >= 0)
{
itemContainer = (ReorderListBoxItem)this.ItemContainerGenerator.ContainerFromIndex(move.ToIndex);
}
if (itemContainer == null)
{
if (temporaryItemContainer == null)
{
temporaryItemContainer = new ReorderListBoxItem();
}
itemContainer = temporaryItemContainer;
itemContainer.Width = itemSize.Width;
itemContainer.Height = itemSize.Height;
this.rearrangeCanvas.Children.Add(itemContainer);
this.PrepareContainerForItemOverride(itemContainer, move.Item);
itemContainer.UpdateLayout();
}
WriteableBitmap itemSnapshot = new WriteableBitmap((int)itemSize.Width, (int)itemSize.Height);
itemSnapshot.Render(itemContainer, null);
itemSnapshot.Invalidate();
Image itemImage = new Image();
itemImage.Width = itemSize.Width;
itemImage.Height = itemSize.Height;
itemImage.Source = itemSnapshot;
itemImage.RenderTransform = new TranslateTransform();
this.rearrangeCanvas.Children.Add(itemImage);
if (itemContainer == temporaryItemContainer)
{
this.rearrangeCanvas.Children.Remove(itemContainer);
}
if (!Double.IsNaN(move.FromY) && !Double.IsNaN(move.ToY))
{
Canvas.SetTop(itemImage, move.FromY);
if (move.FromY != move.ToY)
{
DoubleAnimation moveAnimation = new DoubleAnimation();
moveAnimation.Duration = animationDuration;
Storyboard.SetTarget(moveAnimation, itemImage.RenderTransform);
Storyboard.SetTargetProperty(moveAnimation, new PropertyPath(TranslateTransform.YProperty));
moveAnimation.To = move.ToY - move.FromY;
storyboard.Children.Add(moveAnimation);
}
}
else if (Double.IsNaN(move.FromY) != Double.IsNaN(move.ToY))
{
if (move.FromIndex >= 0 && move.ToIndex >= 0)
{
DoubleAnimation moveAnimation = new DoubleAnimation();
moveAnimation.Duration = animationDuration;
Storyboard.SetTarget(moveAnimation, itemImage.RenderTransform);
Storyboard.SetTargetProperty(moveAnimation, new PropertyPath(TranslateTransform.YProperty));
const double animationDistance = 200;
if (!Double.IsNaN(move.FromY))
{
Canvas.SetTop(itemImage, move.FromY);
if (move.FromIndex < move.ToIndex)
{
moveAnimation.To = animationDistance;
}
else if (move.FromIndex > move.ToIndex)
{
moveAnimation.To = -animationDistance;
}
}
else
{
Canvas.SetTop(itemImage, move.ToY);
if (move.FromIndex < move.ToIndex)
{
moveAnimation.From = -animationDistance;
}
else if (move.FromIndex > move.ToIndex)
{
moveAnimation.From = animationDistance;
}
}
storyboard.Children.Add(moveAnimation);
}
DoubleAnimation fadeAnimation = new DoubleAnimation();
fadeAnimation.Duration = animationDuration;
Storyboard.SetTarget(fadeAnimation, itemImage);
Storyboard.SetTargetProperty(fadeAnimation, new PropertyPath(UIElement.OpacityProperty));
if (Double.IsNaN(move.FromY))
{
itemImage.Opacity = 0.0;
fadeAnimation.To = 1.0;
Canvas.SetTop(itemImage, move.ToY);
}
else
{
itemImage.Opacity = 1.0;
fadeAnimation.To = 0.0;
Canvas.SetTop(itemImage, move.FromY);
}
storyboard.Children.Add(fadeAnimation);
}
}
return storyboard;
}