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内的所有控件上设置此绑定.我确信还有更有效的方法可以做到这一点,但问题并不常见,我坐下来花时间研究如何正确使用制表符范围来避免这种解决方法.
您应该尝试在控件或派生控件上设置KeyboardNavigation.TabNavigation附加属性,以防您的底部按钮也参与选项卡循环:TreeStackPanel
<controls:CustomStackPanel KeyboardNavigation.TabNavigation="Cycle">
<Tree>
...
</Tree>
</controls:CustomStackPanel>
Run Code Online (Sandbox Code Playgroud)
您甚至可以结合使用代码隐藏方法,我假设您正在尝试使用它来控制Tree控件中的选项卡行为,KeyboardNavigation.TabNavigation以便处理树控件外部的选项卡.
不是答案本身,但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的值是什么
最好的祝福,