22// The .NET Foundation licenses this file to you under the MIT license. 
33// See the LICENSE file in the project root for more information. 
44
5+ using  System ; 
56using  System . Linq ; 
67using  System . Numerics ; 
78using  Windows . Foundation ; 
@@ -166,6 +167,16 @@ protected internal override void OnElementContextUninitialized(AttachedShadowEle
166167                _container . Children . Remove ( context . SpriteVisual ) ; 
167168            } 
168169
170+             context . SpriteVisual ? . StopAnimation ( "Size" ) ; 
171+ 
172+             context . Element . LayoutUpdated  -=  Element_LayoutUpdated ; 
173+ 
174+             if  ( context . VisibilityToken  !=  null ) 
175+             { 
176+                 context . Element . UnregisterPropertyChangedCallback ( UIElement . VisibilityProperty ,  context . VisibilityToken . Value ) ; 
177+                 context . VisibilityToken  =  null ; 
178+             } 
179+ 
169180            base . OnElementContextUninitialized ( context ) ; 
170181        } 
171182
@@ -176,6 +187,50 @@ protected override void SetElementChildVisual(AttachedShadowElementContext conte
176187            { 
177188                _container . Children . InsertAtTop ( context . SpriteVisual ) ; 
178189            } 
190+ 
191+             // Handles size changing and other elements around it updating. 
192+             context . Element . LayoutUpdated  -=  Element_LayoutUpdated ; 
193+             context . Element . LayoutUpdated  +=  Element_LayoutUpdated ; 
194+ 
195+             if  ( context . VisibilityToken  !=  null ) 
196+             { 
197+                 context . Element . UnregisterPropertyChangedCallback ( UIElement . VisibilityProperty ,  context . VisibilityToken . Value ) ; 
198+                 context . VisibilityToken  =  null ; 
199+             } 
200+ 
201+             context . VisibilityToken  =  context . Element . RegisterPropertyChangedCallback ( UIElement . VisibilityProperty ,  Element_VisibilityChanged ) ; 
202+         } 
203+ 
204+         private  void  Element_LayoutUpdated ( object  sender ,  object  e ) 
205+         { 
206+             // Update other shadows to account for layout changes 
207+             CastToElement_SizeChanged ( null ,  null ) ; 
208+         } 
209+ 
210+         private  void  Element_VisibilityChanged ( DependencyObject  sender ,  DependencyProperty  dp ) 
211+         { 
212+             if  ( sender  is  FrameworkElement  element ) 
213+             { 
214+                 var  context  =  GetElementContext ( element ) ; 
215+ 
216+                 if  ( element . Visibility  ==  Visibility . Collapsed ) 
217+                 { 
218+                     if  ( _container  !=  null  &&  _container . Children . Contains ( context . SpriteVisual ) ) 
219+                     { 
220+                         _container . Children . Remove ( context . SpriteVisual ) ; 
221+                     } 
222+                 } 
223+                 else 
224+                 { 
225+                     if  ( _container  !=  null  &&  ! _container . Children . Contains ( context . SpriteVisual ) ) 
226+                     { 
227+                         _container . Children . InsertAtTop ( context . SpriteVisual ) ; 
228+                     } 
229+                 } 
230+             } 
231+ 
232+             // Update other shadows to account for layout changes 
233+             CastToElement_SizeChanged ( null ,  null ) ; 
179234        } 
180235
181236        /// <inheritdoc/> 
@@ -255,12 +310,24 @@ protected override CompositionBrush GetShadowMask(AttachedShadowElementContext c
255310            } 
256311
257312            // Position our shadow in the correct spot to match the corresponding element. 
258-             context . SpriteVisual . Size  =  context . Element . RenderSize . ToVector2 ( ) ; 
259313            context . SpriteVisual . Offset  =  context . Element . CoordinatesFrom ( CastTo ) . ToVector3 ( ) ; 
260314
315+             BindSizeAndScale ( context . SpriteVisual ,  context . Element ) ; 
316+ 
261317            return  mask ; 
262318        } 
263319
320+         private  static void  BindSizeAndScale ( CompositionObject  source ,  UIElement  target ) 
321+         { 
322+             var  visual  =  ElementCompositionPreview . GetElementVisual ( target ) ; 
323+             var  bindSizeAnimation  =  source . Compositor . CreateExpressionAnimation ( $ "{ nameof ( visual ) } .Size * { nameof ( visual ) } .Scale.XY") ; 
324+ 
325+             bindSizeAnimation . SetReferenceParameter ( nameof ( visual ) ,  visual ) ; 
326+ 
327+             // Start the animation 
328+             source . StartAnimation ( "Size" ,  bindSizeAnimation ) ; 
329+         } 
330+ 
264331        private  void  CustomMaskedElement_Loaded ( object  sender ,  RoutedEventArgs  e ) 
265332        { 
266333            var  context  =  GetElementContext ( sender  as  FrameworkElement ) ; 
@@ -274,9 +341,6 @@ private void CustomMaskedElement_Loaded(object sender, RoutedEventArgs e)
274341        /// <inheritdoc/> 
275342        protected  internal  override  void  OnSizeChanged ( AttachedShadowElementContext  context ,  Size  newSize ,  Size  previousSize ) 
276343        { 
277-             var  sizeAsVec2  =  newSize . ToVector2 ( ) ; 
278- 
279-             context . SpriteVisual . Size  =  sizeAsVec2 ; 
280344            context . SpriteVisual . Offset  =  context . Element . CoordinatesFrom ( CastTo ) . ToVector3 ( ) ; 
281345
282346            UpdateShadowClip ( context ) ; 
0 commit comments