I have run into issues when hosting a WinForms form within a WindowsFormsHost
and the tab navigation. To solve I have made this simple example:
- Created WPF
Window
(starting point of app) - Created WinForms
Form
with twoTextBox
on it - WPF window: Added
WindowsFormsHost
to it - WPF window: Added
OnLoaded
handler - WPF window: Added
Textbox
positioned under theWindowsFormsHost
In the OnLoaded
handler I got:
System.Windows.Forms.Form f = new WinFormsForm();
f.TopLevel = false;
f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.windowsFormsHost1.Child = f;
When I now run the application:
- Nothing is focussed (ok)
- I click on the first
TextBox
in theWindowsFormsHost
, it gets focus (ok) - I press tab, focus goes to 2nd
TextBox
in theWindowsFormsHost
(ok) - I press tab again, focus goes back to 1st
TextBox
in theWindowsFormsHost
(not ok; should have leftWindowsFormsHost
and given focus to the textbox at the bottom of the WPF window) - I click on the textbox in the wpf (placed after and under the
WindowsFormsHost
), it gets focus (ok) - I press tab, focus goes to 1st textbox in
WindowsFormsHost
- as it should go to beginning after the end. So this is ok too - I click the wpf textbox again and press shift+tab, focus goes to 2nd textbox in
WindowsFormsHost
(ok) - I press tab, focus goes to 1st textbox in
WindowsFormsHost
(goes to beginning in WFH) (not ok)
How do I make the focus behave like if I had only controls of one type? Meaning a tab order of WFH-1st-Textbox, WFH-2nd-Textbox, WPF-Textbox in this case.
According to the articles I have found, that seems not possible to accomplish. According to a MSDN Blog Entry (section Hwnds) the Windows Forms controls always are on top of WPF controls in the hierarchy. The MSDN article (section Acquiring Messages from the WPF Message Loop) states that events occurring in a WindowsFormsHost element will be processed before WPF is even aware of them.
So I assume that the event fired by pressing the TAB key is processed by the WindowsFormsHost element (resulting in the focus of the other textbox). In the enclosing WPF window the event will never be encountered because "it has already been processed". On the other side when you press the TAB key in the WPF textbox, WPF is handling the event itself and the control chain is processed normally. With this the focus will get to a textbox in the WindowsFormsHost element and from there you can't leave it using the keyboard.
I know this will not help your current problem but I hope it explains some things.
ADDENDUM If you are not dependent on using a form control, you could change it into a WinForms user-control with the same control elements in it. After that you change the initialization of the WindowsFormsHost element in the following way:
The class WinFormUC is my WinForms user-control containing the mentioned textboxes. In my test the pressing of the TAB key focused the textboxes one after another regardless whether its a Winforms or a WPF textbox.