in src/Microsoft.Xaml.Behaviors/Core/ExtendedVisualStateManager.cs [1347:1453]
private static Storyboard CreateLayoutTransitionStoryboard(VisualTransition transition, List<FrameworkElement> movingElements, Dictionary<FrameworkElement, double> oldOpacities)
{
Duration duration = transition != null ? transition.GeneratedDuration : new Duration(TimeSpan.Zero);
IEasingFunction ease = transition != null ? transition.GeneratedEasingFunction : null;
Storyboard layoutTransitionStoryboard = new Storyboard();
layoutTransitionStoryboard.Duration = duration;
// Handle the positions of elements that are on the move
foreach (FrameworkElement movingElement in movingElements)
{
WrapperCanvas parentCanvas = movingElement.Parent as WrapperCanvas;
if (parentCanvas == null)
{
continue;
}
{
DoubleAnimation animation = new DoubleAnimation() { From = 1, To = 0, Duration = duration };
animation.EasingFunction = ease;
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(WrapperCanvas.SimulationProgressProperty));
layoutTransitionStoryboard.Children.Add(animation);
// prime the pump
parentCanvas.SimulationProgress = 1;
}
Rect newRect = parentCanvas.NewRect;
// Do-nothing animation to override the width/height of the Canvas without stomping the values, so that the Canvas unwrap will replace the right ones
// Needed in some cases because the width/height may be Auto and the Canvas would shrink to zero size
if (!IsClose(parentCanvas.Width, newRect.Width))
{
DoubleAnimation animation = new DoubleAnimation() { From = newRect.Width, To = newRect.Width, Duration = duration };
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.WidthProperty));
layoutTransitionStoryboard.Children.Add(animation);
}
if (!IsClose(parentCanvas.Height, newRect.Height))
{
DoubleAnimation animation = new DoubleAnimation() { From = newRect.Height, To = newRect.Height, Duration = duration };
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.HeightProperty));
layoutTransitionStoryboard.Children.Add(animation);
}
if (parentCanvas.DestinationVisibilityCache == Visibility.Collapsed)
{
Thickness margin = parentCanvas.Margin;
if (!IsClose(margin.Left, 0) || !IsClose(margin.Top, 0) || !IsClose(margin.Right, 0) || !IsClose(margin.Bottom, 0))
{
ObjectAnimationUsingKeyFrames animation = new ObjectAnimationUsingKeyFrames() { Duration = duration };
DiscreteObjectKeyFrame keyFrame = new DiscreteObjectKeyFrame() { KeyTime = TimeSpan.Zero, Value = new Thickness() };
animation.KeyFrames.Add(keyFrame);
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.MarginProperty));
layoutTransitionStoryboard.Children.Add(animation);
}
if (!IsClose(parentCanvas.MinWidth, 0))
{
DoubleAnimation animation = new DoubleAnimation() { From = 0, To = 0, Duration = duration };
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.MinWidthProperty));
layoutTransitionStoryboard.Children.Add(animation);
}
if (!IsClose(parentCanvas.MinHeight, 0))
{
DoubleAnimation animation = new DoubleAnimation() { From = 0, To = 0, Duration = duration };
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.MinHeightProperty));
layoutTransitionStoryboard.Children.Add(animation);
}
}
}
// Handle the opacity/visibility of elements that are changing visibility
foreach (FrameworkElement visibilityElement in oldOpacities.Keys)
{
WrapperCanvas parentCanvas = visibilityElement.Parent as WrapperCanvas;
if (parentCanvas == null)
{
continue;
}
double oldOpacity = oldOpacities[visibilityElement];
double newOpacity = (parentCanvas.DestinationVisibilityCache == Visibility.Visible ? 1.0 : 0.0);
// Animate the opacity to smooth out the visibility change
if (!IsClose(oldOpacity, 1) || !IsClose(newOpacity, 1))
{
DoubleAnimation animation = new DoubleAnimation() { From = oldOpacity, To = newOpacity, Duration = duration };
animation.EasingFunction = ease;
Storyboard.SetTarget(animation, parentCanvas);
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.OpacityProperty));
layoutTransitionStoryboard.Children.Add(animation);
}
}
return layoutTransitionStoryboard;
}