XAML 我如何显示一个弹出窗口只有当一个关键是被持有?(像记分牌在游戏中)

ao218c7q  于 2023-11-14  发布在  其他
关注(0)|答案(3)|浏览(85)

在一个WPF项目中,我有一个弹出控件,我只想在按住tab键时显示它。一旦松开tab键,它就应该消失。就像电子游戏中的记分牌通常的行为一样。
如何实现这种行为?
我尝试在主窗口上使用PreviewKeyDown和PreviewKeyUp事件来实现它,如下所示:

private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
   if (e.Key == Key.Tab)
   {
        Popup.IsOpen = true;
   }
}

private void Window_PreviewKeyUp(object sender, KeyEventArgs e)
{
   if (e.Key == Key.Tab)
   {
        Popup.IsOpen = true;
   }
}

字符串
这种方法很好用,但是当我按住tab键然后在释放键之前将焦点切换到另一个窗口时,弹出窗口会卡住。有更好的方法解决这个问题吗?

dphi5xsq

dphi5xsq1#

也许可以尝试使用Window.Deactivated事件Window.Deactivated on Microsoft Learn

zpqajqem

zpqajqem2#

一种方法可能是按程序执行。

private void MyView_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (IsVisible)
    {
        Keyboard.AddPreviewKeyDownHandler(Application.Current.MainWindow!, OnPreviewKeyDown);
        Keyboard.AddPreviewKeyUpHandler(Application.Current.MainWindow!, OnPreviewKeyUp);
    }
    else
    {
        Keyboard.RemovePreviewKeyDownHandler(Application.Current.MainWindow!, OnPreviewKeyDown);
        Keyboard.RemovePreviewKeyUpHandler(Application.Current.MainWindow!, OnPreviewKeyUp);            
    }
}

字符串

e0bqpujr

e0bqpujr3#

您应该能够使用本机SetWindowsHookEx API来处理窗口未聚焦时发生的按键:

public partial class MainWindow : Window
{
    private delegate IntPtr Hookproc(int code, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary(string lpLibFileName);

    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(int idHook, Hookproc lpfn, IntPtr hInstance, uint dwThreadId);

    [DllImport("user32.dll")]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll")]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    private readonly Hookproc _hproc;
    private IntPtr _hhook;

    public MainWindow()
    {
        _hproc = HookProc;
        InitializeComponent();
    }

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);

        const int WH_KEYBOARD_LL = 13;
        _hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _hproc, LoadLibrary("User32"), 0);
    }

    protected override void OnClosed(EventArgs e)
    {
        UnhookWindowsHookEx(_hhook);
        base.OnClosed(e);
    }

    private IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam)
    {
        const int WM_KEYDOWN = 0x100;
        const int WM_KEYUP = 0x0101;
        const int VK_TAB = 0x09;
        int keyCode = Marshal.ReadInt32(lParam);
        if (keyCode == VK_TAB)
        {
            if (wParam == WM_KEYDOWN)
                Popup.IsOpen = true;
            else if (wParam == WM_KEYUP)
                Popup.IsOpen = false;
        }

        return CallNextHookEx(_hhook, code, (int)wParam, lParam);
    }
}

字符串

相关问题