C# 通过键盘将焦点移动到捕获元素外部时进行检测
我有以下代码:C# 通过键盘将焦点移动到捕获元素外部时进行检测,c#,.net,wpf,C#,.net,Wpf,我有以下代码: Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapture); 当鼠标点击在我的WPF弹出窗口外时,它会完全捕捉到(所以我可以关闭它) 但是我需要知道焦点是否通过键盘移动到弹出窗口之外。更具体地说,通过快捷方式(即Alt+T) 现在,当用户将焦点移开时,我的
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this,
OnMouseDownOutsideCapture);
当鼠标点击在我的WPF弹出窗口外时,它会完全捕捉到(所以我可以关闭它)
但是我需要知道焦点是否通过键盘移动到弹出窗口之外。更具体地说,通过快捷方式(即Alt+T)
现在,当用户将焦点移开时,我的弹出窗口不会关闭。有什么想法吗?您可以添加一个按键事件,并检查是否按下了alt+tab。我就是这样做的: 将其添加到构造函数中:
EventManager.RegisterClassHandler(typeof(UIElement),
Keyboard.PreviewGotKeyboardFocusEvent,
(KeyboardFocusChangedEventHandler)OnPreviewAnyControlGotKeyboardFocus);
然后添加此事件处理程序:
/// <summary>
/// When focus is lost, make sure that we close the popup if needed.
/// </summary>
private void OnPreviewAnyControlGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
// If we are not open then we are done. No need to go further
if (!IsOpen) return;
// See if our new control is on a popup
var popupParent = VLTreeWalker.FindParentControl<Popup>((DependencyObject)e.NewFocus);
// If the new control is not the same popup in our current instance then we want to close.
if ((popupParent == null) || (this.popup != popupParent))
{
popupParent.IsOpen = false;
}
}
//
///当焦点丢失时,确保在需要时关闭弹出窗口。
///
PreviewAnyControlGotKeyboardFocus上的私有无效(对象发送方,KeyboardFocusChangedEventArgs e)
{
//如果我们不开门,那么我们就完蛋了。没有必要再往前走了
如果(!IsOpen)返回;
//看看我们的新控件是否在弹出窗口上
var popuparent=VLTreeWalker.FindParentControl((DependencyObject)e.NewFocus);
//如果新控件与当前实例中的弹出窗口不同,则我们希望关闭。
if((popuparent==null)| |(this.popup!=popuparent))
{
popupprent.IsOpen=false;
}
}
VLTreeWalker是一个自定义类,它在可视化树上查找与传入泛型类型的匹配项,然后(如果找不到匹配项,它将在逻辑树上遍历。)遗憾的是,我无法在这里轻松发布该类的源代码
this.popup
是您正在比较的实例(您想知道它是否应该关闭)。有一组组合键可以将它们移出弹出窗口(Alt+a、B、E、R、T、S、E…、F12等),我不想对它们全部进行静态编码。尤其是当一个新的程序需要我重新修改代码时(假设我记得这么做)。
/// <summary>
/// When focus is lost, make sure that we close the popup if needed.
/// </summary>
private void OnPreviewAnyControlGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
// If we are not open then we are done. No need to go further
if (!IsOpen) return;
// See if our new control is on a popup
var popupParent = VLTreeWalker.FindParentControl<Popup>((DependencyObject)e.NewFocus);
// If the new control is not the same popup in our current instance then we want to close.
if ((popupParent == null) || (this.popup != popupParent))
{
popupParent.IsOpen = false;
}
}