在 WindowsFormsHost
和选项卡导航中托管WinForms表单时遇到了问题 . 要解决我已经做了这个简单的例子:
-
创建了WPF
Window
(应用的起点) -
创建了WinForms
Form
,上面有两个TextBox
-
WPF窗口:已添加
WindowsFormsHost
-
WPF窗口:添加了
OnLoaded
处理程序 -
WPF窗口:已添加
Textbox
位于WindowsFormsHost
下
在 OnLoaded
处理程序中,我得到了:
System.Windows.Forms.Form f = new WinFormsForm();
f.TopLevel = false;
f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.windowsFormsHost1.Child = f;
当我现在运行应用程序时:
-
什么都没有集中注意力(确定)
-
我点击
WindowsFormsHost
中的第一个TextBox
,它获得焦点(确定) -
我按Tab键,焦点转到
WindowsFormsHost
中的第TextBox
(ok) -
我再次按Tab键,焦点返回到
WindowsFormsHost
中的第TextBox
( not ok;应该离开WindowsFormsHost
并将焦点放在WPF窗口底部的文本框中) -
我点击wpf中的文本框(放在
WindowsFormsHost
之后和之下),它获得焦点(确定) -
我按Tab键,焦点转到
WindowsFormsHost
中的第一个文本框 - 因为它应该在结束后开始 . 所以这也没关系 -
我再次单击wpf文本框并按shift键,焦点转到
WindowsFormsHost
中的第二个文本框(ok) -
我按Tab键,焦点转到
WindowsFormsHost
中的第一个文本框(以WFH开头)( not ok)
如果我只有一种类型的控件,我如何使焦点行为?在这种情况下,意味着WFH-1st-Textbox,WFH-2nd-Textbox,WPF-Textbox的Tab键顺序 .
4 回答
根据我发现的文章,这似乎无法实现 . 根据MSDN Blog Entry(部分Hwnds),Windows窗体控件始终位于层次结构中的WPF控件之上 . MSDN article(从WPF消息循环获取消息部分)指出,在WPF甚至意识到它们之前,将处理WindowsFormsHost元素中发生的事件 .
所以我假设通过按TAB键触发的事件由WindowsFormsHost元素处理(导致其他文本框的焦点) . 在封闭的WPF窗口中,永远不会遇到该事件,因为“它已被处理” . 另一方面,当您按下WPF文本框中的TAB键时,WPF正在处理事件本身并正常处理控制链 . 有了这个,焦点将转到WindowsFormsHost元素中的文本框,从那里你不能使用键盘离开它 .
我知道这不会对你当前的问题有所帮助,但我希望它能解释一些问题 .
ADDENDUM 如果您不依赖于使用表单控件,则可以将其更改为WinForms用户控件,其中包含相同的控件元素 . 之后,您可以通过以下方式更改WindowsFormsHost元素的初始化:
WinFormUC类是我的WinForms用户控件,包含上面提到的文本框 . 在我的测试中,无论是Winforms还是WPF文本框,按下TAB键都会一个接一个地聚焦文本框 .
你可以用一个小技巧来做到这一点 . 假设您的主机wpf表单如下所示:
在第一个文本框的LostFocus事件中,您将焦点设置为winform上的第一个按钮 . 通过这种方式,您可以确保焦点始终从第一个按钮开始 .
在winform中,您必须按如下方式编写EnableTabStops代码:
接下来,您可以通过winform的按钮进行选项卡 . 在输入winform上的最后一个按钮后,您禁用/删除所有tabstops,以便下一个选项卡只能跳转到其父wpf表单,如下所示:
这应该做的工作 .
这是我实现这个的方式:
我创建了一个继承自WindowsFormsHost的控件
对我来说很完美
使用相同的方法,您还可以使您的Windows控件具有所需的wpf数据绑定:
这是XAML:
只需在App.xaml.cs中添加:
System.Windows.Forms.Integration.WindowsFormsHost.EnableWindowsFormsInterop();
参考:WindowsFormsIntegration.dll