我是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));
}
}
}
当我使用导航键时,它的效果很好。除了一个问题。问题是当按下按钮上的向上或向下导航键时,它会跳过一个文本框,它们是按Tab键顺序排列的。我不确定上面代码有什么问题。请建议我应该通过导航键维护标签顺序。
答案 0 :(得分:1)
调用TabOrder是因为焦点在使用Tab键的控件之间切换,而不是箭头键。您的问题是由于某些控件可能会抑制箭头键事件(例如您的TextBox中的TextBox)。但实际上你可以通过这种方式添加事件处理程序来克服这个问题:
textBox.AddHandler(TextBox.KeyDownEvent,
new KeyEventHandler(TextBox_KeyDown),
handledEventsToo: true);
TextBox处理箭头键向下事件,因为它在文本导航中使用这些键。所以TextBox处理它们(移动插入符号)并设置e.Handled = true
,这会使事件从bubbling up停止 - 这就是你没有捕获到这个事件的原因。
但正如我所说,用箭头键导航焦点可能会令用户感到沮丧。您可以使用Tab键导航。 WPF完全支持这种方法,甚至自己设置选项卡索引,以便在用户按Tab键时,焦点从左向右移动,然后从窗口的顶部移动到底部。您可以通过将其IsTabStop
属性设置为false来阻止控件通过Tab键进行聚焦。您还可以通过设置元素“TabIndex
属性来定义自己的Tab键顺序。完全没有代码可以使这种方法有效。
您更喜欢这种方法的另一个原因是您的代码很难维护。看看你的Window_Loaded
处理程序。如果您将来在此窗口中添加一些控件怎么办?您也不必忘记在那里添加代码。如果您的应用程序中出现新窗口怎么办?您将不得不复制此代码块。