Is it possible to detect Keyboard focus events globally?

后端 未结 4 1724
无人及你
无人及你 2021-02-19 12:45

The following events can be used, but, they must be attach for each element:

GotKeyboardFocus, LostKeyboardFocus

Is there a way in .NET WPF to globally detect if

相关标签:
4条回答
  • 2021-02-19 13:28

    You can hook to the tunneling preview events:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="350" Width="525" 
        PreviewGotKeyboardFocus="Window_PreviewGotKeyboardFocus" 
        PreviewLostKeyboardFocus="Window_PreviewLostKeyboardFocus">
    ....
    

    This way, as shown above, the window would be notified before all descendants when any of the descendants gets or loses the keyboard focus.

    Read this for more information.

    0 讨论(0)
  • 2021-02-19 13:29

    You can add a routed event handler to your main window and specify you're interested in handled events.

    mainWindow.AddHandler(
        UIElement.GotKeyboardFocusEvent,
        OnElementGotKeyboardFocus,
        true
    );
    
    0 讨论(0)
  • 2021-02-19 13:34

    You can do this in any class with this:

    //In the constructor
    EventManager.RegisterClassHandler(
            typeof(UIElement),
            Keyboard.PreviewGotKeyboardFocusEvent,
            (KeyboardFocusChangedEventHandler)OnPreviewGotKeyboardFocus);
    

    ...

    private void OnPreviewGotKeyboardFocus(object sender, 
                                           KeyboardFocusChangedEventArgs e)
    {
    
         // Your code here
    
    }
    
    0 讨论(0)
  • 2021-02-19 13:38

    Have a look at how Microsoft trigger CommandManager.RequerySuggested event when focus changes: they subscribe to InputManager.PostProcessInput event.

    ReferenceSource

    Simple example:

    static KeyboardControl()
    {
        InputManager.Current.PostProcessInput += InputManager_PostProcessInput;
    }
    
    static void InputManager_PostProcessInput(object sender, ProcessInputEventArgs e)
    {
        if (e.StagingItem.Input.RoutedEvent == Keyboard.GotKeyboardFocusEvent ||
            e.StagingItem.Input.RoutedEvent == Keyboard.LostKeyboardFocusEvent)
        {
            KeyboardFocusChangedEventArgs focusArgs = (KeyboardFocusChangedEventArgs)e.StagingItem.Input;
            KeyboardControl.IsOpen = focusArgs.NewFocus is TextBoxBase;
        }
    }
    

    This also works in multi-window applications.

    0 讨论(0)
提交回复
热议问题