Monday, October 08, 2007 9:30 PM
Tamir Khason
Focus Management and mouse wheel hooking on WinForms by using WPF
Someone asked very interesting question in MSDN forums. I was sure, that that's kind of "I forgot something small", however, I built small repro.
public partial class Window1 : System.Windows.Window
{
public Window1()
{
InitializeComponent();
UserControl1 uc = new UserControl1();
WindowsFormsHost wfh = new WindowsFormsHost();
wfh.Child = (System.Windows.Forms.Control)uc;
((Grid)this.Content).Children.Add(wfh);
}
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
const int WM_MOUSEWHEEL = 0x20A;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_MOUSEWHEEL)
label1.Text = (int)m.WParam > 0 ? "Scrolling up" : "Scrolling down";
}
However, I noticed, that hosted WinForms control receives mouse notification only after it was clicked. What's the ****, I thought. It was not reasonable for me, so I hooked into WindowsFormsHost.Loaded and UserControl.Load event to set focus manually by code.
....uc.Load += new EventHandler(uc_Load);
....wfh.Loaded += new RoutedEventHandler(wfh_Loaded);
void wfh_Loaded(object sender, RoutedEventArgs e)
{
FocusManager.SetFocusedElement((DependencyObject)sender, (IInputElement)sender);
}
void uc_Load(object sender, EventArgs e)
{
((UserControl1)sender).Focus();
}
No effect. The user control inside WindowsFormsHost got not focus. Digging deeper, I found interesting article about focus management in WPF Interop application. So, using System.Windows.Interop.IKeyboardInputSink.TabInto(System.Windows.Input.TraversalRequest) solves the problem. Just one line of code and Interop control, hosted in WPF got the focus, that it requests.
((System.Windows.Interop.IKeyboardInputSink)sender).TabInto(new System.Windows.Input.TraversalRequest(FocusNavigationDirection.First));
Well, next time, I advice to MSDN doc team, to write small bullet and link to such simple solution, that has to occur (as for me) automatically, when I set focus to WindowsFormsHost WPF element.
תגים:WPF, Tips and Tricks, WPF crossbow