In WPF I can specify that a control container is a Focus Scope and that tab navigation should cycle through the controls (i.e. when I tab out of the final control, focus will return to the first):
<Border FocusManager.IsFocusScope="True" KeyboardNavigation.TabNavigation="Cycle">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox x:Name="Editor" Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
What I am trying to do is to detect when开发者_如何学Python focus leaves the final field. Without knowing precisely the number of controls within the focus scope, does anyone know if this is possible?
This functionality does not appear to be built into WPF, as you seem to have discovered.
My recommendation would be to build an attached behavior to handle this.
If you have Blend and can use System.Windows.Interactivity, simply derive from the Behavior class and override OnAttached and OnDetached. Otherwise, write a static behavior class as demonstrated here.
When the behavior is attached, save the first (current?) focused item and subscribe to a focus changed event. In the event handler, track the focused item within the focus scope (the scope the behavior is applied to). When the focused item returns to the first item, fire a routed event. There are some details that would have to be worked out.
For the sake of closing off this question, I'm changing my comment to an answer. The solution was essentially to keep a record of selected item within the view model and react to changes to that. As a general rule I don't think the view model should be aware of control focus, but in this case I think it is required as the view model needs to react to focus changes.
In the end I was able to work around my specific problem using the default collection view to keep a record of the current item, and some attached properties to keep this in line with the current keyboard focus
精彩评论