WPF Tab键导航

12 c# navigation wpf controls

我们有一个基于WPF .NET 4.0 C#的应用程序.我们从XML定义(而不是XAML)构建了我们的用户界面,但在下面我们使用WPF来呈现UI.那是在运行时,我们根据XML定义创建WPF UI.

我们在标签导航方面遇到了问题.我们为文本和组合框控件设置TabStop,TabIndex.
但是标签导航无效.如何使标签导航适用于此布局?

在此输入图像描述

Rac*_*hel 37

WPF将整个UI树视为单个Tab范围.它没有像你期望的那样被分解成更小的区域.这包括UserControls中的控件.

例如,如果你有

<StackPanel>
    <TextBox Name="TextBox1" />
    <MyUserControl />
    <TextBox Name="TextBox3" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

MyUserControl看起来像

<MyUserControl>
    <TextBox Name="TextBox2"  />
</MyUserControl>
Run Code Online (Sandbox Code Playgroud)

默认的选项卡循环是TextBox1,TextBox2,TextBox3.这是因为没有定义TabIndex属性,因此所有控件都以默认的Tab键顺序运行,这是它们添加到UI的顺序.

如果在控件上设置TabIndex,如下图所示,

<StackPanel>
    <TextBox Name="TextBox1" TabIndex="1" />
    <MyUserControl TabIndex="2" />
    <TextBox Name="TextBox3" TabIndex="3" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

您的标签将更改为TextBox1,TextBox3,TextBox2.这是因为TextBox2没有指定TabIndex,所以默认是假定的,并且在指定了TabIndex的所有其他控件之后,它会被选中.

我通常解决这个问题的方法是将TabIndexUserControl中的控件绑定到UserControl.TabIndex.

例如,将以下绑定添加到UserControl将使Tab循环再次正确

<MyUserControl>
    <TextBox Name="TextBox2" TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" />
</MyUserControl>
Run Code Online (Sandbox Code Playgroud)

我通常喜欢Loaded在UserControl 的情况下设置此绑定,而不必记住在UserControl内的所有控件上设置此绑定.我确信还有更有效的方法可以做到这一点,但问题并不常见,我坐下来花时间研究如何正确使用制表符范围来避免这种解决方法.


Max*_*lov 9

您应该尝试在控件或派生控件上设置KeyboardNavigation.TabNavigation附加属性,以防您的底部按钮也参与选项卡循环:TreeStackPanel

<controls:CustomStackPanel KeyboardNavigation.TabNavigation="Cycle">
 <Tree>
 ...
 </Tree>
</controls:CustomStackPanel>
Run Code Online (Sandbox Code Playgroud)

您甚至可以结合使用代码隐藏方法,我假设您正在尝试使用它来控制Tree控件中的选项卡行为,KeyboardNavigation.TabNavigation以便处理树控件外部的选项卡.


Dr.*_*ABT 5

不是答案本身,但WPF标签非常繁琐.需要在Xaml中设置TabNavigation,IsTabStop属性并摆弄焦点范围.我花了好几天时间单独尝试使用Xaml进行跳转.我建议从你的XML开始 - > WPF模型真的应该是Xaml - > WPF!但是我想这是不可能的.

如何解决此问题.您是否可以在生成的代码中处理Tab键?如果您的WPF用户控件是由您自己的XML从您自己的XML生成的,那么我建议在您的XML中放置一个TabOrder元素,然后使用它来连接TabOut事件.

查看以下代码示例以强制执行代码中的移动操作(类似于Tabbing)

// 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);
}
Run Code Online (Sandbox Code Playgroud)

然后连接到"tabbable"控件的KeyUp(或PreviewKeyUp)事件,如果键是tab,则调用上面的代码使焦点跳转到下一个元素.

上面的代码示例基本上会在代码中强制WPF应该开箱即用.正如其他海报所建议的那样,我会查看生成的WPF代码,看看KeyboardNavigation.IsTabStop和KeyboardNavigation.TabNavigation的值是什么

最好的祝福,