@@ -67,10 +67,27 @@ public TimeSpan FocusEngagementTimeout
67
67
}
68
68
69
69
/// <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
+ }
71
79
72
80
/// <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
+ }
74
91
75
92
private static void OnTargetsPropertyChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
76
93
{
@@ -92,24 +109,39 @@ private void ApplyFocus()
92
109
}
93
110
94
111
var focusedControlIndex = - 1 ;
112
+ var listViewBaseControls = 0 ;
95
113
for ( var i = 0 ; i < Targets . Count ; i ++ )
96
114
{
97
115
var control = Targets [ i ] . Control ;
116
+ if ( control is null )
117
+ {
118
+ continue ;
119
+ }
120
+
98
121
if ( control . IsLoaded )
99
122
{
100
123
if ( control . Focus ( FocusState . Programmatic ) )
101
124
{
102
125
focusedControlIndex = i ;
103
126
break ;
104
127
}
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
+ }
105
136
}
106
137
else
107
138
{
139
+ control . Loaded -= OnControlLoaded ;
108
140
control . Loaded += OnControlLoaded ;
109
141
}
110
142
}
111
143
112
- if ( focusedControlIndex == 0 || Targets . All ( t => t . Control ? . IsLoaded == true ) )
144
+ if ( focusedControlIndex == 0 || ( listViewBaseControls == 0 && Targets . All ( t => t . Control ? . IsLoaded == true ) ) )
113
145
{
114
146
// The first control has received the focus or all the control are loaded and none can take the focus: we stop.
115
147
Stop ( ) ;
@@ -137,6 +169,14 @@ private void OnEngagementTimerTick(object sender, object e)
137
169
138
170
private void OnControlLoaded ( object sender , RoutedEventArgs e ) => ApplyFocus ( ) ;
139
171
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
+
140
180
private void Stop ( FocusTargetList targets = null )
141
181
{
142
182
if ( _timer != null )
@@ -153,6 +193,11 @@ private void Stop(FocusTargetList targets = null)
153
193
}
154
194
155
195
target . Control . Loaded -= OnControlLoaded ;
196
+
197
+ if ( target . Control is ListViewBase listViewBase )
198
+ {
199
+ listViewBase . ContainerContentChanging -= OnContainerContentChanging ;
200
+ }
156
201
}
157
202
}
158
203
}
@@ -167,7 +212,7 @@ public sealed class FocusTargetList : List<FocusTarget>
167
212
/// <summary>
168
213
/// A target for the <see cref="FocusBehavior"/>.
169
214
/// </summary>
170
- public sealed partial class FocusTarget : DependencyObject
215
+ public sealed class FocusTarget : DependencyObject
171
216
{
172
217
/// <summary>
173
218
/// The DP to store the <see cref="Control"/> property value.
@@ -176,7 +221,13 @@ public sealed partial class FocusTarget : DependencyObject
176
221
nameof ( Control ) ,
177
222
typeof ( Control ) ,
178
223
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 ;
180
231
181
232
/// <summary>
182
233
/// Gets or sets the control that will receive the focus.
@@ -186,6 +237,12 @@ public Control Control
186
237
get => ( Control ) GetValue ( ControlProperty ) ;
187
238
set => SetValue ( ControlProperty , value ) ;
188
239
}
240
+
241
+ private static void OnControlChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
242
+ {
243
+ var target = ( FocusTarget ) d ;
244
+ target . ControlChanged ? . Invoke ( target , EventArgs . Empty ) ;
245
+ }
189
246
}
190
247
#pragma warning restore SA1402 // File may only contain a single type
191
248
}
0 commit comments