Search code examples
c#wpfuser-controlsfocuskeyboard-events

Ctrl+Left/Right moves focus to other control


I have a WinForms usercontrol (ZedGraphControl) hosted on a WindowsFormsHost WPF control, placed in a nested Grid. When I attempt to handle Ctrl+Left/Right in the WinForms control code the control looses focus, and focus moves to control in the grid cell to the Left/Right.

What may cause this, and how can the behavior be disabled?

Edit: The behavior is triggered if a DataGrid is in the grid cell to the left or right, with cells displayed that can take focus. Also if a TextBox is there, possibly any control that can take editable focus.


Solution

  • Sounds like something in your WPF universe is intercepting those key combinations and using them to move focus. At first, I thought it might be WPF's built-in directional keyboard navigation, but based on your edits, I think it might be something else.

    Whatever is happening, you might be able to prevent it by overriding some keyboard processing behavior in WindowsFormsHost.

    public class WindowsFormsHostEx : WindowsFormsHost
    {
        protected override bool TranslateAcceleratorCore(ref MSG msg, ModifierKeys modifiers)
        {
            const int vkLeft = 0x25;
            const int vkRight = 0x27;
    
            if (modifiers == ModifierKeys.Control &&
                ((int)msg.wParam == vkLeft || (int)msg.wParam == vkRight))
            {
                var m = Message.Create(msg.hwnd, msg.message, msg.wParam, msg.lParam);
                this.Child?.WindowTarget?.OnMessage(ref m);
                return true;
            }
    
            return base.TranslateAcceleratorCore(ref msg, modifiers);
        }
    }
    

    Based on my tests, this causes the WindowsFormsHostEx to 'claim' all Ctrl+Left/Right keystrokes when the host has focus. It dispatches them to the hosted WinForms content, with WPF apparently carrying on as if the event never happened.