Wpf 保持键控向上和键控向下的选项卡顺序

Wpf 保持键控向上和键控向下的选项卡顺序,wpf,tabs,navigation,key,Wpf,Tabs,Navigation,Key,我是WPF新手,在我的应用程序中,我希望通过导航键(向上/向下箭头键)保持选项卡顺序。所以我在窗口加载事件中迭代网格中的每个控件,并添加委托,如下所示 private void Window_Loaded(object sender, RoutedEventArgs e) { foreach (UIElement element in gridChild.Children) { if (elemen

我是WPF新手,在我的应用程序中,我希望通过导航键(向上/向下箭头键)保持选项卡顺序。所以我在窗口加载事件中迭代网格中的每个控件,并添加委托,如下所示

private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            foreach (UIElement element in gridChild.Children)
            {
                if (element.GetType() == typeof(TextBox))
                {
                    TextBox tb1 = (TextBox)element;
                    tb1.PreviewKeyUp += TextBox_KeyDown;
                }
                else if (element.GetType() == typeof(PasswordBox))
                {
                    PasswordBox tb1 = (PasswordBox)element;
                    tb1.PreviewKeyUp += TextBox_KeyDown;
                }
                else if (element.GetType() == typeof(Button))
                {
                    Button tb1 = (Button)element;
                    tb1.PreviewKeyDown += TextBox_KeyDown;
                }
            }
}
private void TextBox_KeyDown(Object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down || (e.Key == Key.Enter && sender.GetType()!=typeof(Button))  )
            {
                e.Handled = true;
                UIElement focusedElement = Keyboard.FocusedElement as UIElement;
                if (focusedElement != null)
                {
                    focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }



            }
            else if (e.Key == Key.Up)
            {



                e.Handled = true;
                UIElement focusedElement = Keyboard.FocusedElement as UIElement;
                if (focusedElement != null)
                {
                    focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
                }
            }
        }
汉德勒在后面

private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            foreach (UIElement element in gridChild.Children)
            {
                if (element.GetType() == typeof(TextBox))
                {
                    TextBox tb1 = (TextBox)element;
                    tb1.PreviewKeyUp += TextBox_KeyDown;
                }
                else if (element.GetType() == typeof(PasswordBox))
                {
                    PasswordBox tb1 = (PasswordBox)element;
                    tb1.PreviewKeyUp += TextBox_KeyDown;
                }
                else if (element.GetType() == typeof(Button))
                {
                    Button tb1 = (Button)element;
                    tb1.PreviewKeyDown += TextBox_KeyDown;
                }
            }
}
private void TextBox_KeyDown(Object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down || (e.Key == Key.Enter && sender.GetType()!=typeof(Button))  )
            {
                e.Handled = true;
                UIElement focusedElement = Keyboard.FocusedElement as UIElement;
                if (focusedElement != null)
                {
                    focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }



            }
            else if (e.Key == Key.Up)
            {



                e.Handled = true;
                UIElement focusedElement = Keyboard.FocusedElement as UIElement;
                if (focusedElement != null)
                {
                    focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
                }
            }
        }

除了一个问题外,当我使用导航键时,它工作得很好。问题是当按下按钮上的向上或向下导航键时,它会跳过下一个文本框,而下一个文本框是按选项卡顺序排列的。我不确定上面的代码有什么问题。请建议如何通过导航键维护选项卡顺序。

之所以调用TabOrder,是因为焦点是在使用tab键而不是箭头键的控件之间切换的。您的问题是由于某些控件可能会抑制箭头键事件造成的,例如案例中的TextBox。但实际上,您可以通过以下方式添加事件处理程序来克服此问题:

textBox.AddHandler(TextBox.KeyDownEvent, 
                   new KeyEventHandler(TextBox_KeyDown), 
                   handledEventsToo: true);
TextBox处理向下箭头键事件,因为它在文本导航中使用这些键。因此,文本框将处理它们(移动插入符号)并设置
e.Handled=true
,这将从停止事件-这就是您无法捕获此事件的原因

但正如我所说,使用箭头键导航焦点可能会让用户感到沮丧。您可以使用Tab键导航。WPF完全支持这种方法,甚至可以自行设置选项卡索引,以便在用户按tab键时,焦点从窗口的左到右,然后从窗口的顶部到底部移动。通过将控件的
IsTabStop
属性设置为false,可以防止控件被Tab键聚焦。您还可以通过设置元素“
TabIndex
属性”来定义自己的选项卡顺序。使这种方法工作完全不需要代码

与您实现的方法相比,您更喜欢这种方法的另一个原因是您的代码很难维护。查看加载的
窗口处理程序。如果将来向该窗口添加一些控件,会怎么样?您也不必忘记在那里添加代码。如果应用程序中出现新窗口,该怎么办?您必须复制这段代码