我们遇到了选项卡导航问题。我们为文本和组合框控件设置了TabStop、TabIndex,但选项卡导航不起作用。如何使此布局的选项卡导航正常工作?
WPF将整个UI树视为单个Tab范围。它没有分成较小的区域,如您所期望的那样。这包括UserControl内部的控件。
例如,如果您有
<StackPanel>
<TextBox Name="TextBox1" />
<MyUserControl />
<TextBox Name="TextBox3" />
</StackPanel>
而 MyUserControl
看起来像这样
<MyUserControl>
<TextBox Name="TextBox2" />
</MyUserControl>
默认的选项卡顺序将是TextBox1、TextBox2、TextBox3。这是因为未定义TabIndex属性,因此所有控件都按照默认的选项卡顺序运行,即它们添加到UI中的顺序。
如果您在控件上设置了类似下面的TabIndex:
<StackPanel>
<TextBox Name="TextBox1" TabIndex="1" />
<MyUserControl TabIndex="2" />
<TextBox Name="TextBox3" TabIndex="3" />
</StackPanel>
你的Tab键顺序将变为TextBox1、TextBox3、TextBox2。这是因为TextBox2没有指定TabIndex,因此默认情况下会在所有指定了TabIndex的控件循环后进行Tab键切换。
我通常的解决方法是将UserControl内部控件的TabIndex
绑定到UserControl.TabIndex。
例如,将以下绑定添加到UserControl中将使Tab键循环正确:
<MyUserControl>
<TextBox Name="TextBox2" TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" />
</MyUserControl>
我通常更喜欢在UserControl的Loaded
事件中设置此绑定,而不是记住在UserControl内的所有控件上都要设置此绑定。我相信还有更有效的方法来完成这个任务,但是这个问题并没有经常出现,所以我没有花时间研究如何正确使用选项卡范围来避免这种解决办法。
如果想让底部按钮也参与Tab键顺序,可以尝试在Tree
控件或派生自StackPanel
的控件上设置KeyboardNavigation.TabNavigation附加属性:
<controls:CustomStackPanel KeyboardNavigation.TabNavigation="Cycle">
<Tree>
...
</Tree>
</controls:CustomStackPanel>
您甚至可以将代码后端方法与KeyboardNavigation.TabNavigation
相结合,以控制树形控件内的标签行为,并处理树形控件外的标签。
虽然不是一个特定的答案,但WPF切换标签非常棘手。需要在Xaml中设置TabNavigation、IsTabStop属性,并调整焦点范围。我已经花了几天时间尝试只使用Xaml来正确处理切换标签。我建议从你的XML -> WPF模型开始,真正应该是Xaml -> WPF!然而,我想象这是不可能的。
那么这个解决方法怎么样?您是否能够在生成的代码中处理切换标签?如果您自己的软件从自己的XML生成WPF用户控件,那么建议在您的XML中放置一个TabOrder元素,然后使用它来连接一个TabOut事件。
查看以下代码示例,以在代码中强制执行移动操作(类似于切换标签)
// Creating a FocusNavigationDirection object to perform the tab operation
// values include Next, Previous, First, Last etc...
FocusNavigationDirection focusDirection = FocusNavigationDirection.Next;
// MoveFocus takes a TraveralReqest as its argument.
TraversalRequest request = new TraversalRequest(focusDirection);
// Gets the element with keyboard focus.
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;
// Change keyboard focus.
if (elementWithFocus != null)
{
elementWithFocus.MoveFocus(request);
}
尝试 KeyboardNavigation.TabNavigation="Once"