WPF Tab键导航

时间:2011-12-17 19:40:57

标签: c# wpf navigation controls

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

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

enter image description here

4 个答案:

答案 0 :(得分:36)

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

例如,如果你有

<StackPanel>
    <TextBox Name="TextBox1" />
    <MyUserControl />
    <TextBox Name="TextBox3" />
</StackPanel>

MyUserControl看起来像

<MyUserControl>
    <TextBox Name="TextBox2"  />
</MyUserControl>

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

如果您在控件上设置TabIndex,例如下面的

<StackPanel>
    <TextBox Name="TextBox1" TabIndex="1" />
    <MyUserControl TabIndex="2" />
    <TextBox Name="TextBox3" TabIndex="3" />
</StackPanel>

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

我通常解决这个问题的方法是将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内的所有控件上设置此绑定。我确信也有更有效的方法来做到这一点,但问题并不常见,让我坐下来花时间研究如何正确使用制表符范围来避免这种解决方法。

答案 1 :(得分:9)

如果您希望底部按钮也参与制表符循环,则应尝试在Tree控件或StackPanel派生控件上设置KeyboardNavigation.TabNavigation附加属性:

<controls:CustomStackPanel KeyboardNavigation.TabNavigation="Cycle">
 <Tree>
 ...
 </Tree>
</controls:CustomStackPanel>

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

答案 2 :(得分:5)

不是答案本身,但WPF标签非常繁琐。需要在Xaml中设置TabNavigation,IsTabStop属性并摆弄焦点范围。我花了好几天时间单独尝试使用Xaml进行跳转。我建议从你的XML开始 - &gt; WPF模型真的应该是Xaml - &gt; 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);
}

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

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

致以最诚挚的问候,

答案 3 :(得分:0)

尝试 KeyboardNavigation.TabNavigation = “一次”