diff --git a/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedDropShadow.cs b/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedDropShadow.cs
index 070603cb7d0..f6fe707a7cf 100644
--- a/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedDropShadow.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedDropShadow.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Linq;
using System.Numerics;
using Windows.Foundation;
@@ -166,6 +167,16 @@ protected internal override void OnElementContextUninitialized(AttachedShadowEle
_container.Children.Remove(context.SpriteVisual);
}
+ context.SpriteVisual?.StopAnimation("Size");
+
+ context.Element.LayoutUpdated -= Element_LayoutUpdated;
+
+ if (context.VisibilityToken != null)
+ {
+ context.Element.UnregisterPropertyChangedCallback(UIElement.VisibilityProperty, context.VisibilityToken.Value);
+ context.VisibilityToken = null;
+ }
+
base.OnElementContextUninitialized(context);
}
@@ -176,6 +187,50 @@ protected override void SetElementChildVisual(AttachedShadowElementContext conte
{
_container.Children.InsertAtTop(context.SpriteVisual);
}
+
+ // Handles size changing and other elements around it updating.
+ context.Element.LayoutUpdated -= Element_LayoutUpdated;
+ context.Element.LayoutUpdated += Element_LayoutUpdated;
+
+ if (context.VisibilityToken != null)
+ {
+ context.Element.UnregisterPropertyChangedCallback(UIElement.VisibilityProperty, context.VisibilityToken.Value);
+ context.VisibilityToken = null;
+ }
+
+ context.VisibilityToken = context.Element.RegisterPropertyChangedCallback(UIElement.VisibilityProperty, Element_VisibilityChanged);
+ }
+
+ private void Element_LayoutUpdated(object sender, object e)
+ {
+ // Update other shadows to account for layout changes
+ CastToElement_SizeChanged(null, null);
+ }
+
+ private void Element_VisibilityChanged(DependencyObject sender, DependencyProperty dp)
+ {
+ if (sender is FrameworkElement element)
+ {
+ var context = GetElementContext(element);
+
+ if (element.Visibility == Visibility.Collapsed)
+ {
+ if (_container != null && _container.Children.Contains(context.SpriteVisual))
+ {
+ _container.Children.Remove(context.SpriteVisual);
+ }
+ }
+ else
+ {
+ if (_container != null && !_container.Children.Contains(context.SpriteVisual))
+ {
+ _container.Children.InsertAtTop(context.SpriteVisual);
+ }
+ }
+ }
+
+ // Update other shadows to account for layout changes
+ CastToElement_SizeChanged(null, null);
}
///
@@ -255,12 +310,24 @@ protected override CompositionBrush GetShadowMask(AttachedShadowElementContext c
}
// Position our shadow in the correct spot to match the corresponding element.
- context.SpriteVisual.Size = context.Element.RenderSize.ToVector2();
context.SpriteVisual.Offset = context.Element.CoordinatesFrom(CastTo).ToVector3();
+ BindSizeAndScale(context.SpriteVisual, context.Element);
+
return mask;
}
+ private static void BindSizeAndScale(CompositionObject source, UIElement target)
+ {
+ var visual = ElementCompositionPreview.GetElementVisual(target);
+ var bindSizeAnimation = source.Compositor.CreateExpressionAnimation($"{nameof(visual)}.Size * {nameof(visual)}.Scale.XY");
+
+ bindSizeAnimation.SetReferenceParameter(nameof(visual), visual);
+
+ // Start the animation
+ source.StartAnimation("Size", bindSizeAnimation);
+ }
+
private void CustomMaskedElement_Loaded(object sender, RoutedEventArgs e)
{
var context = GetElementContext(sender as FrameworkElement);
@@ -274,9 +341,6 @@ private void CustomMaskedElement_Loaded(object sender, RoutedEventArgs e)
///
protected internal override void OnSizeChanged(AttachedShadowElementContext context, Size newSize, Size previousSize)
{
- var sizeAsVec2 = newSize.ToVector2();
-
- context.SpriteVisual.Size = sizeAsVec2;
context.SpriteVisual.Offset = context.Element.CoordinatesFrom(CastTo).ToVector3();
UpdateShadowClip(context);
diff --git a/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedShadowElementContext.cs b/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedShadowElementContext.cs
index 1d8803d23af..63afa4581e3 100644
--- a/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedShadowElementContext.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Shadows/AttachedShadowElementContext.cs
@@ -20,6 +20,8 @@ public sealed class AttachedShadowElementContext
private Dictionary _resources;
+ internal long? VisibilityToken { get; set; }
+
///
/// Gets a value indicating whether or not this has been initialized.
///