WPF:关注关键事件

WPF: Focus on keyevents

在我的 "real" 解决方案中,我有一个文本框,当用户按下(文本框为空)时,焦点必须转移到另一个控件。

如果我在 "another control" 上按 "down-arrow",我必须聚焦文本框,但现在文本框捕获相同的 "down" 事件并将焦点设置到另一个控件。

让我用一个例子展示一下....

<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

这是我想要它做的...

实际情况如下...

然后我想到了使用KeyUp事件...

Private Sub button2_PreviewKeyUp(sender As Object, e As KeyEventArgs) Handles button2.PreviewKeyUp
    e.Handled = True
    Me.textBox.Focus()
End Sub

...但是我无法将焦点移至 Button2。

我不能在TextBox上使用KeyDown,因为我需要检查文本框的内容,而且它只能在KeyUp事件中使用。

我知道这很简单,但我一直盯着自己看。

求助:)

这肯定是一个有趣的情况。 这里的主要问题是向下箭头已经用于某些控件(如按钮)之间的导航。那么会发生什么是按钮在 KeyDown 事件上执行默认焦点切换,然后您的事件处理程序对 KeyUp 起作用 - 但焦点已经移动!

所以要解决这个问题,我们需要使用默认导航,而不是反对它。
首先,对于按钮:没有手动事件处理。此外,我们需要通过 IsTabStop 属性 从 Tab 键顺序中删除最后一个。并且不要让焦点离开我们的 StackPanel 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>

然后,文本框。我们需要切换到 KeyDown 否则它会遇到同样的问题。这对我们来说无关紧要,因为我们真正检查内容的唯一时间是按下向下箭头(它不会更改文本,对吗?)。但是我们需要将事件标记为已处理以停止它:

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