WPF:专注于关键事件

时间:2016-02-17 10:52:25

标签: wpf vb.net keyboard-events

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

如果我按下“另一个控件”上的“向下箭头”,我就会关注文本框,但现在文本框会捕获相同的“向下”事件并将焦点设置到另一个控件。

让我用样品展示它......

<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

这就是我想要它做的......

  • 手动将焦点放在文本框
  • 按“向下箭头”转到Button1
  • 按“向下箭头”转到Button2
  • 按“向下箭头”转到TextBox
  • 不做任何其他事情

这是实际发生的事情......

  • 手动将焦点放在文本框
  • 按“向下箭头”转到Button1
  • 按“向下箭头”转到Button2
  • 按“向下箭头”转到TextBox
  • 焦点自动移至Button1

然后我想到了使用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事件中使用。

我知道这只是一件简单的事,但我已经瞎了眼。

帮助:)

1 个答案:

答案 0 :(得分:0)

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

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

然后,TextBox。我们需要切换到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