Можно ли обнаружить события фокуса клавиатуры глобально?
Можно использовать следующие события, но они должны быть прикреплены для каждого элемента:
GotKeyboardFocus, LostKeyboardFocus
Есть ли способ в .NET WPF глобально определить, изменился ли сфокусированный элемент? без необходимости добавлять слушателей событий для всех возможных элементов?
Ответы
Ответ 1
Вы можете подключиться к туннелированию событий предварительного просмотра:
<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">
....
Таким образом, как показано выше, окно будет уведомлено перед всеми потомками, когда любой из потомков получает или теряет фокус клавиатуры.
Подробнее читайте .
Ответ 2
Вы можете сделать это в любом классе с помощью этого:
//In the constructor
EventManager.RegisterClassHandler(
typeof(UIElement),
Keyboard.PreviewGotKeyboardFocusEvent,
(KeyboardFocusChangedEventHandler)OnPreviewGotKeyboardFocus);
...
private void OnPreviewGotKeyboardFocus(object sender,
KeyboardFocusChangedEventArgs e)
{
// Your code here
}
Ответ 3
Вы можете добавить обработчик маршрутизированного события в основное окно и указать, что вы заинтересованы в обработанных событиях.
mainWindow.AddHandler(
UIElement.GotKeyboardFocusEvent,
OnElementGotKeyboardFocus,
true
);
Ответ 4
Посмотрите, как Microsoft запускает событие CommandManager.RequerySuggested
при изменении фокуса: они подписываются на InputManager.PostProcessInput
событие.
ReferenceSource
Простой пример:
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;
}
}
Это также работает в многооконных приложениях.