【问题标题】:Stop keyboard directional navigation jumping out from one usercontrol to another停止键盘方向导航从一个用户控件跳到另一个
【发布时间】:2016-02-09 19:38:20
【问题描述】:

我创建了非常简单的布局来显示我的问题。基本上我在另一个用户控件(浏览)中有一个用户控件(表单),现在我希望能够使用 tab 和 ctrl+tab 循环浏览表单,它确实如此。但我注意到,当我在任何按钮(表单内)上按下箭头键时,它会跳出表单以进行浏览。所以我将键盘的方向导航设置为无,但它忽略了它,仍然允许我用箭头键导航。如何确保我无法通过键盘退出该表单?

这里是 xaml

<Window xmlns:wpfApplication1="clr-namespace:WpfApplication1">
<Grid>
<Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
    <RowDefinition />
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" FontSize="36" Text="This is a browse" />
<wpfApplication1:Form Grid.Row="1"/>
<StackPanel Grid.Row="2"
            HorizontalAlignment="Center"
            Orientation="Horizontal">
    <Button Height="50" Width="300">move previous</Button>
    <Button Height="50" Width="300">move next</Button>
</StackPanel>
</Grid>
</Window>

<UserControl x:Class="WpfApplication1.Form"
     Margin="30"
     Background="Gray"
     KeyboardNavigation.ControlTabNavigation="Cycle"
     KeyboardNavigation.DirectionalNavigation="None"
     KeyboardNavigation.TabNavigation="Cycle">
<Grid>
<Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
    <TextBlock VerticalAlignment="Center" Text="First Name:" />
    <TextBox Width="500"
             Height="50"
             HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Grid.Row="1"
            Grid.ColumnSpan="2"
            HorizontalAlignment="Center"
            Orientation="Horizontal">
    <Button Width="200"
            Height="50"
            Content="Save" />
    <Button Width="200"
            Height="50"
            Content="Close" />
</StackPanel>
</Grid>

谢谢你:)

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    来自MSDN

    KeyboardNavigationMode 值:

    - 此容器内不允许使用键盘导航。

    这意味着不允许使用键导航从该容器外部进入该容器。

    你要找的是:

    包含 - 根据导航的方向,当到达容器的结尾或开头时,焦点会返回到第一个或最后一个项目,但不会移过容器的开头或结尾

    【讨论】:

    • 感谢您的回答,请问有没有办法完全停止按箭头键导航?
    • 您可以在窗口级别停止它,在根窗口上设置KeyboardNavigation.DirectionalNavigation="Once"。但是您不应该对此感到困惑,定向导航是用户交互的有用部分。
    • 非常感谢,它正是我所需要的。我不需要在按钮之间导航或离开表单即可使用箭头键进行浏览。因此,选项卡将在表单上循环,如果用户想要退出表单,则选项卡以保存或取消并按下它。幸运的是,我仍然可以通过将 DirectionalNavigation 设置为“一次通过列表框”进行导航(刚刚测试过)。不过有一件事我不明白,为什么必须将其设置为“一次”,我尝试将其设置为“无”,但它不起作用。它没有意义,但它可以在窗口级别使用一次,然后影响所有表单:)
    【解决方案2】:

    您可以为按钮添加 PreviewKeyDown 的处理程序以覆盖箭头键事件。

    <Button PreviewKeyDown="Button_PreviewKeyDown" />
    

    和代码:

    private void Button_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.IsDown && e.Key == Key.Down || e.Key == Key.Up || e.Key == Key.Left || e.Key == Key.Right)
        {
            e.Handled = true;
        }
    }
    

    编辑:

    如果您希望使用样式为所有按钮添加处理程序,您可以使用 EventSetter 来做到这一点:

    <UserControl.Resources>
        <Style TargetType="{x:Type Button}">
            <EventSetter Event="PreviewKeyDown" Handler="Button_PreviewKeyDown"/>
        </Style>
    </UserControl.Resources>
    

    【讨论】:

    • 谢谢您的回答,没有更好的解决方案吗?因为我有很多地方我不得不做这样的事情。我在想会有一个 xaml 解决方案,然后我可以将其转换为一种样式,因此它适用于任何地方。
    • 您可以为所有按钮(或任何其他控件)添加相同的事件,就像您必须应用相同的样式一样,因此差别不大。如果您希望保留 MVVM,则可以添加附加属性,但这只是更多代码,但您可以看看这个问题:http://stackoverflow.com/questions/11096621/wpf-disable-arrow-keys-on-tabcontrol
    • 谢谢。我会在上面回答,你的也可以。但另一个允许我将它设置在一个地方(单 xaml 行也是如此),我不必在任何地方引用它:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    相关资源
    最近更新 更多