开发者

How do I capture key down in WPF?

How do I capture a key down event in WP开发者_如何学JAVAF even if my application is not focused?


For me, the best way is this:

public MainWindow()
{
    InitializeComponent();

    CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
}

void CompositionTarget_Rendering(object sender, EventArgs e)
{
    if ((Keyboard.GetKeyStates(Key.W) & KeyStates.Down) > 0)
    {
        player1.walk();
    }
} 

The rendering event runs every time.


Global keyboard hook can slow down your debugging.

I prefer to use this approach:

  1. Create KeyboardListener class

    public class KeyboardListener : IDisposable
    {
        private readonly Thread keyboardThread;
    
        //Here you can put those keys that you want to capture
        private readonly List<KeyState> numericKeys = new List<KeyState>
        {
            new KeyState(Key.D0),
            new KeyState(Key.D1),
            new KeyState(Key.D2),
            new KeyState(Key.D3),
            new KeyState(Key.D4),
            new KeyState(Key.D5),
            new KeyState(Key.D6),
            new KeyState(Key.D7),
            new KeyState(Key.D8),
            new KeyState(Key.D9),
            new KeyState(Key.NumPad0),
            new KeyState(Key.NumPad1),
            new KeyState(Key.NumPad2),
            new KeyState(Key.NumPad3),
            new KeyState(Key.NumPad4),
            new KeyState(Key.NumPad5),
            new KeyState(Key.NumPad6),
            new KeyState(Key.NumPad7),
            new KeyState(Key.NumPad8),
            new KeyState(Key.NumPad9),
            new KeyState(Key.Enter)
        };
    
        private bool isRunning = true;
    
        public KeyboardListener()
        {
            keyboardThread = new Thread(StartKeyboardListener) { IsBackground = true };
            keyboardThread.Start();
        }
    
        private void StartKeyboardListener()
        {
            while (isRunning)
            {
                Thread.Sleep(15);
                if (Application.Current != null)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        if (Application.Current.Windows.Count > 0)
                        {
                            foreach (var keyState in numericKeys)
                            {
                                if (Keyboard.IsKeyDown(keyState.Key) && !keyState.IsPressed) //
                                {
                                    keyState.IsPressed = true;
                                    KeyboardDownEvent?.Invoke(null, new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromDependencyObject(Application.Current.Windows[0]), 0, keyState.Key));
                                }
    
                                if (Keyboard.IsKeyUp(keyState.Key))
                                {
                                    keyState.IsPressed = false;
                                }
                            }
                        }
                    });
                }
            }
        }
    
        public event KeyEventHandler KeyboardDownEvent;
    
        /// <summary>
        /// Состояние клавиши
        /// </summary>
        private class KeyState
        {
            public KeyState(Key key)
            {
                this.Key = key;
            }
    
            public Key Key { get; }
            public bool IsPressed { get; set; }
        }
    
        public void Dispose()
        {
            isRunning = false;
            Task.Run(() =>
            {
                if (keyboardThread != null && !keyboardThread.Join(1000))
                {
                    keyboardThread.Abort();
                }
            });
        }
    }
    
  2. Subscribe to KeyboardDownEvent in code-behind (or where you need it).

    public partial class MainWindow : Window
    {
        private KeyboardListener listener;
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            listener = new KeyboardListener();
            listener.KeyboardDownEvent += ListenerOnKeyPressed;
        }
    
        private void ListenerOnKeyPressed(object sender, KeyEventArgs e)
        {
            // TYPE YOUR CODE HERE
        }
    
        private void Window_OnUnloaded(object sender, RoutedEventArgs e)
        {
            listener.KeyboardDownEvent -= ListenerOnKeyPressed;
        }
    }
    
  3. Done


See this questions for hooking the keyboard Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜