如何覆盖或操作 KeyDown:Space 或 Enter for ListView in UWP?

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

我已将 KeyDown 事件附加到我的 Win 10 UWP 应用中的 ListView。我想让 VirtualKey.Enter 有一个特殊的效果,但是事件没有触发这个特定的键。 Space、向上或向下箭头也没有。我猜这是因为列表视图已经为这些键定义了特殊行为。

不过我想重写其中一些键,或者至少触发其他操作。即使使用修饰符(例如 Shift+ArrowDown)将事件附加到那些键上也不起作用,因为事件仍然没有触发。

I read 对于 WPF,有一个可以附加的 PreviewKeyDown 事件。不过,我找不到 UWP 的那个事件。还有其他选择吗?

这是一种方法:订阅全局 Window.Current.CoreWindow.KeyDown 事件。 然后保存列表视图的焦点状态并做出相应的反应。

这是代码:

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

您还需要为您的 ListView 订阅 xaml 中的焦点事件:

<ListView .... GotFocus="myList_GotFocus" LostFocus="myList_LostFocus"/>

斯蒂芬妮的回答很好,在一般情况下都有效。但是,正如 Nilzor 所观察到的,它在 ListView 的 Enter 键的情况下不起作用。出于某种原因,ListView 会在按下 Enter 时处理 KeyDown 事件。

正如问题所问,处理 ListView 时处理关键事件的更好方法是这样。

 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)
        {

        }
    }

注意 AddHandler 函数中的最后一个参数。这指定我们是否要处理已经由可视化树中的前一个元素处理过的事件。 当然不要忘记适时退订

Corcus 的解决方案对我不起作用。有效的是直接从 XAML 处理 PreviewKeyDown。适用于 SPACEENTER 键:

XAML:

<ListView PreviewKeyDown="BookmarksListView_PreviewKeyDown">

后面的代码:

private void BookmarksListView_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
    if (e.Key == Windows.System.VirtualKey.Enter)
    {
        // DO YOUR STUFF...
        e.Handled = true;
    }
}

您可以使用 AddHandler 方法。

private void KeyEnterEventHandler(object sender, KeyRoutedEventArgs e)
    {
        if (e.OriginalKey == Windows.System.VirtualKey.Enter)
        {
            PlayFromListView();
        }
    }
    private void LoadListView()
    {
        foreach (var music in playListStorageFile.PlayList)
        {
            ListViewItem item = new ListViewItem();
            item.AddHandler(FrameworkElement.KeyDownEvent, new KeyEventHandler(KeyEnterEventHandler), true);

            TextBlock mytext = new TextBlock();
            mytext.Text = music.Nro.ToString() + " - " + music.Name;
            mytext.Tag = music.Nro;
            item.Content = mytext;
            lvMusics.Items.Add(item);
        }
    }

https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.uielement.addhandler?view=winrt-18362