Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过键盘将焦点移动到捕获元素外部时进行检测_C#_.net_Wpf - Fatal编程技术网

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;
        }
    }