@@ -67,10 +67,27 @@ public TimeSpan FocusEngagementTimeout
6767 }
6868
6969 /// <inheritdoc/>
70- protected override void OnAssociatedObjectLoaded ( ) => ApplyFocus ( ) ;
70+ protected override void OnAssociatedObjectLoaded ( )
71+ {
72+ foreach ( var target in Targets )
73+ {
74+ target . ControlChanged += OnTargetControlChanged ;
75+ }
76+
77+ ApplyFocus ( ) ;
78+ }
7179
7280 /// <inheritdoc/>
73- protected override void OnDetaching ( ) => Stop ( ) ;
81+ protected override bool Uninitialize ( )
82+ {
83+ foreach ( var target in Targets )
84+ {
85+ target . ControlChanged -= OnTargetControlChanged ;
86+ }
87+
88+ Stop ( ) ;
89+ return true ;
90+ }
7491
7592 private static void OnTargetsPropertyChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
7693 {
@@ -92,24 +109,39 @@ private void ApplyFocus()
92109 }
93110
94111 var focusedControlIndex = - 1 ;
112+ var listViewBaseControls = 0 ;
95113 for ( var i = 0 ; i < Targets . Count ; i ++ )
96114 {
97115 var control = Targets [ i ] . Control ;
116+ if ( control is null )
117+ {
118+ continue ;
119+ }
120+
98121 if ( control . IsLoaded )
99122 {
100123 if ( control . Focus ( FocusState . Programmatic ) )
101124 {
102125 focusedControlIndex = i ;
103126 break ;
104127 }
128+
129+ if ( control is ListViewBase listViewBase )
130+ {
131+ // The list may not have any item yet, we wait until the first item is rendered.
132+ listViewBase . ContainerContentChanging -= OnContainerContentChanging ;
133+ listViewBase . ContainerContentChanging += OnContainerContentChanging ;
134+ listViewBaseControls ++ ;
135+ }
105136 }
106137 else
107138 {
139+ control . Loaded -= OnControlLoaded ;
108140 control . Loaded += OnControlLoaded ;
109141 }
110142 }
111143
112- if ( focusedControlIndex == 0 || Targets . All ( t => t . Control ? . IsLoaded == true ) )
144+ if ( focusedControlIndex == 0 || ( listViewBaseControls == 0 && Targets . All ( t => t . Control ? . IsLoaded == true ) ) )
113145 {
114146 // The first control has received the focus or all the control are loaded and none can take the focus: we stop.
115147 Stop ( ) ;
@@ -137,6 +169,14 @@ private void OnEngagementTimerTick(object sender, object e)
137169
138170 private void OnControlLoaded ( object sender , RoutedEventArgs e ) => ApplyFocus ( ) ;
139171
172+ private void OnTargetControlChanged ( object sender , EventArgs e ) => ApplyFocus ( ) ;
173+
174+ private void OnContainerContentChanging ( ListViewBase sender , ContainerContentChangingEventArgs args )
175+ {
176+ sender . ContainerContentChanging -= OnContainerContentChanging ;
177+ ApplyFocus ( ) ;
178+ }
179+
140180 private void Stop ( FocusTargetList targets = null )
141181 {
142182 if ( _timer != null )
@@ -153,6 +193,11 @@ private void Stop(FocusTargetList targets = null)
153193 }
154194
155195 target . Control . Loaded -= OnControlLoaded ;
196+
197+ if ( target . Control is ListViewBase listViewBase )
198+ {
199+ listViewBase . ContainerContentChanging -= OnContainerContentChanging ;
200+ }
156201 }
157202 }
158203 }
@@ -167,7 +212,7 @@ public sealed class FocusTargetList : List<FocusTarget>
167212 /// <summary>
168213 /// A target for the <see cref="FocusBehavior"/>.
169214 /// </summary>
170- public sealed partial class FocusTarget : DependencyObject
215+ public sealed class FocusTarget : DependencyObject
171216 {
172217 /// <summary>
173218 /// The DP to store the <see cref="Control"/> property value.
@@ -176,7 +221,13 @@ public sealed partial class FocusTarget : DependencyObject
176221 nameof ( Control ) ,
177222 typeof ( Control ) ,
178223 typeof ( FocusTarget ) ,
179- new PropertyMetadata ( null ) ) ;
224+ new PropertyMetadata ( null , OnControlChanged ) ) ;
225+
226+ /// <summary>
227+ /// Raised when <see cref="Control"/> property changed.
228+ /// It can change if we use x:Load on the control.
229+ /// </summary>
230+ public event EventHandler ControlChanged ;
180231
181232 /// <summary>
182233 /// Gets or sets the control that will receive the focus.
@@ -186,6 +237,12 @@ public Control Control
186237 get => ( Control ) GetValue ( ControlProperty ) ;
187238 set => SetValue ( ControlProperty , value ) ;
188239 }
240+
241+ private static void OnControlChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
242+ {
243+ var target = ( FocusTarget ) d ;
244+ target . ControlChanged ? . Invoke ( target , EventArgs . Empty ) ;
245+ }
189246 }
190247#pragma warning restore SA1402 // File may only contain a single type
191248}
0 commit comments