WPF Tab 键导航
我们有一个基于 WPF .NET 4.0 C# 的应用程序。我们根据 XML 定义(而不是 XAML)构建用户界面,但在底层我们使用 WPF 来呈现 UI。也就是说,在运行时,我们根据 XML 定义创建 WPF UI。
我们在选项卡导航方面遇到问题。我们为文本和组合框控件设置TabStop、TabIndex。
但选项卡导航不起作用。如何使选项卡导航适用于此布局?
We have a WPF .NET 4.0 C# based application. We built our user interface from XML definitions (not XAML) but underneath we use a WPF to present the UI. That is at runtime, we create the WPF UI based on our XML definition.
We have a problem with tab navigation. We set TabStop, TabIndex, for text and combo box controls.
But tab navigation is not working. How to make tab navigation work for this layout?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
WPF 将整个 UI 树视为单个选项卡范围。它并没有像您所期望的那样被分成更小的区域。这包括 UserControls 内的控件。
例如,如果您的
MyUserControl
看起来像这样,则默认选项卡循环将为 TextBox1、TextBox2、TextBox3。这是因为未定义 TabIndex 属性,因此所有控件都按默认 Tab 键顺序运行,即它们添加到 UI 的顺序。
如果您在控件上设置 TabIndex(如下所示),
您的选项卡将更改为 TextBox1、TextBox3、TextBox2。这是因为 TextBox2 没有指定 TabIndex,因此采用默认值,并且在指定了 TabIndex 的所有其他控件循环通过后,它会被切换到。
我通常解决这个问题的方法是将 UserControl 内的控件的
TabIndex
绑定到 UserControl.TabIndex。例如,将以下绑定添加到 UserControl 将使 Tab 循环再次正确
我通常更喜欢在 UserControl 的 Loaded 事件中设置此绑定,而不必记住在所有控件上设置此绑定在用户控件内。我确信也有更有效的方法来做到这一点,但是问题并没有经常出现,让我坐下来花时间研究如何正确使用选项卡范围以避免这种解决方法。
WPF treats the entire UI Tree as a single Tab scope. It isn't broken up into smaller areas such as you would expect. This includes controls inside UserControls.
For example, if you had
And
MyUserControl
looked likeThe default tab cycle would be TextBox1, TextBox2, TextBox3. This is because no TabIndex properties are defined, so all controls run at the default tab order, which is the order in which they're added to the UI.
If you set the TabIndex on your controls such as below,
Your tabbing would change to TextBox1, TextBox3, TextBox2. This is because TextBox2 doesn't have a TabIndex specified, so the default is assumed and it is tabbed to after all the other controls with a TabIndex specified get cycled through.
The way I usually get around this is to bind the
TabIndex
of controls inside the UserControl to the UserControl.TabIndex.For example adding the following binding to the UserControl would make the Tab cycle correct again
I usually prefer to set this binding in the
Loaded
event of the UserControl instead of having to remember to set this binding on all the controls inside the UserControl. I'm sure there are also more efficient ways of doing this as well, however the problem has not come up often enough for me to sit down and take the time to research how to use tab scopes correctly to avoid this workaround.您应该尝试在任一设备上设置 KeyboardNavigation.TabNavigation 附加属性您的
Tree
控件或StackPanel
派生控件,如果您希望底部按钮也参与选项卡循环:您甚至可以结合您所使用的代码隐藏方法,我假设,当前正在尝试使用
KeyboardNavigation.TabNavigation
来控制树控件内的选项卡行为,以处理树控件外部的选项卡。You should try setting a KeyboardNavigation.TabNavigation attached property on either your
Tree
control, or theStackPanel
derived control, in case you want your bottom buttons to also participate in a tab cycle:You can even combine a code-behind approach that you, I assume, is currently trying to use to control the tab behaviour inside the Tree control, with the
KeyboardNavigation.TabNavigation
to take care of the tabbing outside the tree control.本身不是答案,但 WPF 选项卡非常繁琐。需要在 Xaml 中设置 TabNavigation、IsTabStop 属性并调整焦点范围。我花了几天时间尝试单独使用 Xaml 来正确进行制表符操作。我建议从 XML 开始 -> WPF 模型确实应该是 Xaml ->世界和平基金会!但我认为这是不可能的。
这是一个解决方法怎么样?您可以在生成的代码中处理制表符吗?如果您的 WPF 用户控件是由您自己的软件从您自己的 XML 生成的,那么我建议您将 TabOrder 元素放入您的 XML 中,然后使用它来连接 TabOut 事件。
查看下面的代码示例,在代码中强制执行移动操作(类似于 Tabbing)
其次,连接到“可选项”控件的 KeyUp(或 PreviewKeyUp)事件,如果键是 Tab,则调用上面的代码以使焦点跳转到下一个元素。
上面的代码示例基本上将在代码中强制执行 WPF 应该立即执行的操作。正如其他发帖者建议的那样,我将检查您生成的 WPF 代码,看看 KeyboardNavigation.IsTabStop 和 KeyboardNavigation.TabNavigation 的值是什么
最好的问候,
Not an answer per-se but WPF tabbing is extremely fiddly. Requires setting the TabNavigation, IsTabStop properties in Xaml and fiddling around with focus scope. I have spent days trying to get tabbing right using Xaml alone. I would suggest to begin with your XML -> WPF model really ought to be Xaml -> WPF! However I would imagine that's not possible.
How about this for a workaround. Is it possible for you to handle the tabbing in generated code? If your WPF usercontrols are generated by your own software from your own XML then I'd suggest putting a TabOrder element in your XML and then using that to wire up a TabOut event.
Look at the following code sample to force a move operation in code (Similar to Tabbing)
Secondly wire in to the KeyUp (or PreviewKeyUp) event of your "tabbable" controls and if the key was tab call the above code to cause focus to jump to the next element.
The above code sample will basically force in code what WPF should do out of the box. As other posters have suggested I would go through your generated WPF code to see what the values of KeyboardNavigation.IsTabStop and KeyboardNavigation.TabNavigation
Best regards,
尝试
KeyboardNavigation.TabNavigation="一次"
Try
KeyboardNavigation.TabNavigation="Once"