11using System ;
2- using System . ComponentModel ;
32using System . Windows . Controls ;
43using System . Windows ;
54using System . Windows . Media ;
@@ -17,11 +16,51 @@ public static string GetToAnimateControlName(Expander element) =>
1716 public static void SetToAnimateControlName ( Expander element , string value ) =>
1817 element . SetValue ( ToAnimateControlNameProperty , value ) ;
1918
19+ private const string DefaultAnimationTargetPartName = "ExpanderContent" ;
2020 public static readonly DependencyProperty ToAnimateControlNameProperty = DependencyProperty . RegisterAttached (
2121 "ToAnimateControlName" ,
2222 typeof ( string ) ,
2323 typeof ( ExpanderAnimationsHelper ) ,
24- new PropertyMetadata ( "ExpanderContent" ) ) ;
24+ new PropertyMetadata ( DefaultAnimationTargetPartName , OnToAnimateControlNameChanged ) ) ;
25+
26+ private static void OnToAnimateControlNameChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
27+ {
28+ if ( d is Expander expander )
29+ {
30+ expander . SetValue ( CachedToAnimateControlProperty , null ) ;
31+ }
32+ }
33+
34+ #endregion
35+
36+ #region CachedToAnimateControl
37+
38+ private static FrameworkElement GetAnimationTarget ( Expander expander )
39+ {
40+ if ( expander . GetValue ( CachedToAnimateControlProperty ) is FrameworkElement target )
41+ {
42+ return target ;
43+ }
44+
45+ var animationTargetName = GetToAnimateControlName ( expander ) ;
46+
47+ if ( expander . Template ? . FindName ( animationTargetName , expander ) is not FrameworkElement toAnimateControl )
48+ {
49+ expander . ApplyTemplate ( ) ;
50+ toAnimateControl = expander . Template ? . FindName ( animationTargetName , expander ) as FrameworkElement ??
51+ throw new ArgumentNullException ( "ToAnimateControl" , $ "Couldn't find the Border part to animate either update the ExpanderAnimationsHelper.ToAnimateControlName or rename the animation target part to default: { DefaultAnimationTargetPartName } ") ;
52+ }
53+
54+ expander . SetValue ( CachedToAnimateControlProperty , toAnimateControl ) ;
55+ return toAnimateControl ;
56+ }
57+
58+ private static readonly DependencyProperty CachedToAnimateControlProperty =
59+ DependencyProperty . RegisterAttached (
60+ "CachedToAnimateControl" ,
61+ typeof ( FrameworkElement ) ,
62+ typeof ( ExpanderAnimationsHelper ) ,
63+ new PropertyMetadata ( null ) ) ;
2564
2665 #endregion
2766
@@ -130,9 +169,10 @@ private static void OnExpanderExpandedOrCollapsed(object sender, RoutedEventArgs
130169 /// <seealso href="https://github.com/iNKORE-NET/UI.WPF.Modern/issues/402"/>
131170 private static void InitializeExpanderState ( Expander expander )
132171 {
172+ CacheToAnimateControl ( expander ) ;
133173 // On initial load, set the content to the appropriate state immediately
134174 // without animation to avoid a visual flash
135- var toAnimateControl = GetToAnimateControl ( expander ) ;
175+ var toAnimateControl = GetAnimationTarget ( expander ) ;
136176 if ( toAnimateControl == null )
137177 {
138178 return ;
@@ -174,8 +214,10 @@ private static void RunExpanderAnimation(Expander expander)
174214
175215 private static void AnimateExpand ( Expander expander )
176216 {
177- var toAnimateControl = GetToAnimateControl ( expander ) ;
217+ var toAnimateControl = GetAnimationTarget ( expander ) ;
178218 toAnimateControl . BeginAnimation ( UIElement . VisibilityProperty , null ) ;
219+ toAnimateControl . Visibility = Visibility . Visible ;
220+
179221 UpdateLayout ( toAnimateControl ) ;
180222
181223 if ( toAnimateControl . RenderTransform is not TranslateTransform translateTransform )
@@ -189,7 +231,7 @@ private static void AnimateExpand(Expander expander)
189231
190232 private static void AnimateCollapse ( Expander expander )
191233 {
192- var toAnimateControl = GetToAnimateControl ( expander ) ;
234+ var toAnimateControl = GetAnimationTarget ( expander ) ;
193235 var animationDuration = GetCollapseAnimationDuration ( expander ) ;
194236
195237 var visibilityAnimation = new ObjectAnimationUsingKeyFrames
@@ -269,8 +311,5 @@ private static void UpdateLayout(FrameworkElement contentControl)
269311 contentControl . Measure ( new Size ( contentControl . MaxWidth , contentControl . MaxHeight ) ) ;
270312 contentControl . UpdateLayout ( ) ;
271313 }
272-
273- private static FrameworkElement GetToAnimateControl ( Expander expander ) =>
274- expander . Template ? . FindName ( GetToAnimateControlName ( expander ) , expander ) as FrameworkElement ;
275314 }
276315}
0 commit comments