Reputation: 4528
In my "real" solution I have a textbox and when user presses down (and the textbox is empty), focus must be shifted to another control.
If I press "down-arrow" on the "another control", I hav to focus the textbox, but now the textbox catches the same "down" event and set focus to the another control.
Let me show it with a sample....
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/>
<Button x:Name="button1" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="0,10,0,0"/>
<Button x:Name="button2" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="0,10,0,0"/>
<Button x:Name="button3" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="0,10,0,0"/>
</StackPanel>
</Grid>
</Window>
Class MainWindow
Private Sub textBox_PreviewKeyUp(sender As Object, e As KeyEventArgs) Handles textBox.PreviewKeyUp
If Me.textBox.Text = "" AndAlso e.Key = Key.Down Then
Me.button1.Focus()
End If
End Sub
Private Sub button2_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles button2.PreviewKeyDown
e.Handled = True
Me.textBox.Focus()
End Sub
End Class
Here's what I want it to do...
Here's what actually happens...
Then I thought of using the KeyUp event...
Private Sub button2_PreviewKeyUp(sender As Object, e As KeyEventArgs) Handles button2.PreviewKeyUp
e.Handled = True
Me.textBox.Focus()
End Sub
... but then I can't move focus to Button2.
I can't use KeyDown on the TextBox, because I need to check the content of the textbox and it's only available in the KeyUp event.
I know it's properly just a simple thing, but I've stared myself blind.
Help :)
Upvotes: 1
Views: 807
Reputation: 4774
That's an interesting situation for sure. The main problem here is that down arrow is already used for navigation between some controls like buttons. So what happens is the button executes default focus switch on KeyDown event and then your event handler acts on KeyUp - but the focus was already moved!
So to fix this we need to play with default navigation, not against it.
First, for the buttons: no manual event handling. Also, we need to remove last one from the tab order via IsTabStop
property. And don't let the focus move away of our StackPanel with KeyboardNavigation.DirectionalNavigation:
<StackPanel KeyboardNavigation.DirectionalNavigation="Cycle">
<TextBox x:Name="textBox" Text="" PreviewKeyDown="textBox_PreviewKeyDown" />
<Button x:Name="button1" Content="Button" />
<Button x:Name="button2" Content="Button" />
<Button x:Name="button3" Content="Button" IsTabStop="False" />
</StackPanel>
Then, TextBox. We need to switch to KeyDown
or it will suffer from the same issue. It does not matter for us, because the only time we really check the contents is when Down arrow is pressed (and it won't change the text, right?). But we need to mark the event as handled to stop it:
Private Sub textBox_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles textBox.PreviewKeyDown
If Me.textBox.Text = "" AndAlso e.Key = Key.Down Then
e.Handled = True
Me.button1.Focus()
End If
End Sub
Upvotes: 1