Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I override or act on KeyDown: Space or Enter for ListView in UWP?

Tags:

winrt-xaml

uwp

I've attached the KeyDown event to a ListView in my Win 10 UWP app. I want to make VirtualKey.Enter have a special effect, but the event is not firing for this particular key. Neither does it for Space, Arrow up or down. This I guess because the listview already has defined a special behaviour for those keys.

I'd like to override some of those keys though, or at least trigger additional actions. Even attaching events to those key with modifiers (e.g. Shift+ArrowDown) would not work because the events still are not firing.

I read that for WPF that there is a PreviewKeyDown-event which one can attach to. I can't find that event for UWP though. Are there any other options?

like image 748
Nilzor Avatar asked May 22 '16 16:05

Nilzor


2 Answers

Stephanie's answer is a good one and it works in the general case. However, as Nilzor observed it will not work in the case of a ListView for the Enter key. For some reason the ListView handles the KeyDown event in case Enter is pressed.

A better way to handle key events when dealing with a ListView, as the question asks, is this.

 private void ListView_Loaded(object sender, RoutedEventArgs e)
    {
        (sender as ListView).AddHandler(UIElement.KeyDownEvent, new KeyEventHandler(ListView_KeyDown), true);
    }

 private void ListView_KeyDown(object sender, KeyRoutedEventArgs args)
    {
        if (args.Key == Windows.System.VirtualKey.Enter)
        {

        }
    }

Notice the last argument in the AddHandler function. This specifies whether we want to handle events already handled by a previous element in the visual tree. Of course don't forget to unsubscribe from the event when appropriate

like image 168
Corcus Avatar answered Jan 01 '23 08:01

Corcus


Here is one way to do it : subscribe to the global Window.Current.CoreWindow.KeyDown event. Then save the focus state of your listview and react accordingly.

Here is the code :

public sealed partial class MainPage : Page
{
    bool hasFocus = false;
    public MainPage()
    {
        this.InitializeComponent();
        Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
    }

    private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
    {
        if(hasFocus)
        {
            Debug.Write("Key down on list");
        }
    }

    private void myList_GotFocus(object sender, RoutedEventArgs e)
    {
        hasFocus = true;

    }

    private void myList_LostFocus(object sender, RoutedEventArgs e)
    {
        hasFocus = false;
    }

You will also need to subscribe to the focus events in xaml, for your ListView :

<ListView .... GotFocus="myList_GotFocus" LostFocus="myList_LostFocus"/>
like image 22
Stéphanie Hertrich Avatar answered Jan 01 '23 10:01

Stéphanie Hertrich