下列事件都可以使用,但是,他們必須重視每一個元素:是否有可能在全球範圍內檢測鍵盤焦點事件?
GotKeyboardFocus,LostKeyboardFocus
是否有.NET WPF的方式在全球範圍內檢測是否聚焦元素改變了嗎?而不必爲所有可能的元素添加事件監聽器?
下列事件都可以使用,但是,他們必須重視每一個元素:是否有可能在全球範圍內檢測鍵盤焦點事件?
GotKeyboardFocus,LostKeyboardFocus
是否有.NET WPF的方式在全球範圍內檢測是否聚焦元素改變了嗎?而不必爲所有可能的元素添加事件監聽器?
你可以連接到tunneling預覽事件:
<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瞭解更多信息。
您可以將路由事件處理程序添加到主窗口並指定您對處理的事件感興趣。
mainWindow.AddHandler(
UIElement.GotKeyboardFocusEvent,
OnElementGotKeyboardFocus,
true
);
工作完美!非常感謝! – Alexey 2014-05-09 08:08:59
您可以在任何類此這樣做:
//In the constructor
EventManager.RegisterClassHandler(
typeof(UIElement),
Keyboard.PreviewGotKeyboardFocusEvent,
(KeyboardFocusChangedEventHandler)OnPreviewGotKeyboardFocus);
...
private void OnPreviewGotKeyboardFocus(object sender,
KeyboardFocusChangedEventArgs e)
{
// Your code here
}
看一看微軟如何觸發CommandManager.RequerySuggested
事件當焦點的變化:他們訂閱InputManager.PostProcessInput
事件。
簡單的例子:
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;
}
}
這也適用於多窗口的應用程序。
由於這是一個預覽事件,因此此方法可能會導致錯誤結果,因此焦點更改可能不會真正發生。如果窗口和源元素之間的UIElement將事件標記爲已處理,則會發生這種情況。 – Hank 2014-02-03 20:26:34
我同意@Hank。 PreviewXxx不保證它實際上會改變。 Vaccano的答案其實是正確的。尼古拉斯也有替代品,儘管並不完全一樣,因爲處理事件的失敗導致連鎖店中的每個人都得到通知。 – MarqueIV 2015-11-04 16:24:17