Handle alt key(s) in UWP application
Asked Answered
B

2

6

I'm using KeyDown and KeyUp handlers on Window.Current.CoreWindow to catch keystrokes in a VNC application for UWP. This works great with one exception: alt (VirtualKey.Menu/LeftMenu/RightMenu) never is sent to my application. In addition, alt+letter results in neither being sent to the handlers.

I assume that this is because some accelerator handler is eating these events before they reach CoreWindow. Is there any way around this?

Boarding answered 12/7, 2016 at 21:53 Comment(0)
M
14

Try to use Dispatcher.AcceleratorKeyActivated instead, it handles Alt key.

Also, it seems there is an issue with CoreWindow. More details on MSDN

Matronize answered 14/7, 2016 at 22:34 Comment(3)
This is absolutely, exactly what I needed. Thank you so much! I'll reward the bounty in 23 hours when it opens up. Can't believe I didn't find this in all my googling.Boarding
I'm glad it helped! :)Matronize
You also need to add if (!args.KeyStatus.IsMenuKeyDown) return; at the start of Dispatcher.AcceleratorKeyActivated implementation, otherwise it will react on key presses even if ALT key is not hold.Isosceles
H
0

Here an example of how I managed to solve this issue in Xamarin Forms.

// A model to store the values of the key event.
public class KeyEventArgs : EventArgs
{
    public bool IsAltKeyPressed { get; set; }

    public string Key { get; set; }
}

// UWP Custom render
public class MyPageViewRenderer : PageRenderer
{
    /// <summary>
    /// Monitor windows core ui keypress when MyPageView is showing
    /// </summary>
    public MyPageViewRenderer() : base()
    {
        // When ExplorePage appears then attach to the ui core keydown event
        Loaded += (object sender, RoutedEventArgs e) =>
        {
            CoreWindow.GetForCurrentThread().Dispatcher.AcceleratorKeyActivated += Dispatcher_AcceleratorKeyActivated;
        };

        // When ExplorePage disappears then detach from the ui core keydown event
        Unloaded += (object sender, RoutedEventArgs e) =>
        {
            CoreWindow.GetForCurrentThread().Dispatcher.AcceleratorKeyActivated -= Dispatcher_AcceleratorKeyActivated;
        };
    }

    private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
    {
        if ((args.EventType == CoreAcceleratorKeyEventType.KeyDown || args.EventType == CoreAcceleratorKeyEventType.SystemKeyDown)
            && !args.KeyStatus.WasKeyDown)
        {
            bool isAltKeyPressed = args.KeyStatus.IsMenuKeyDown;
            (Element as MyPageView).MyPageView_KeyPressed(Element, new KeyEventArgs { IsAltKeyPressed = isAltKeyPressed, Key = args.VirtualKey.ToString() });
        }
    }
}

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyPageView : ContentPage
{
    public MyPageView()
    {
        InitializeComponent();

        this.Focus();
    }

    public void MyPageView_KeyPressed(object sender, KeyEventArgs e)
    {

        (this.BindingContext as MyPageViewModel).CommandOnKeyPress?.Execute(e);
        
    }
}
Heritor answered 1/8, 2020 at 5:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.