【问题标题】:How can I override or act on KeyDown: Space or Enter for ListView in UWP?如何覆盖或操作 KeyDown:UWP 中 ListView 的 Space 或 Enter?
【发布时间】:2016-05-22 16:01:08
【问题描述】:

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

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

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

【问题讨论】:

  • 您是否真的对这些按键感兴趣,或者您想修改标准行为,这些按键在控件中触发?
  • 我对按键感兴趣。对于空间,我想调用一个动作而不是取消选择该项目。对于左右箭头,我还想调用一个动作
  • 在这些情况下,我通常将事件附加到父控件上,然后检查焦点控件是否是我正在寻找的控件,然后执行所需的逻辑。我不知道在 UWP 上有任何其他解决方法。
  • 有关信息...PreviewKeyDown 现在在 UWP 中可用

标签: winrt-xaml uwp


【解决方案1】:

Stephanie 的回答很好,它适用于一般情况。但是,正如 Nilzor 所观察到的,它在 Enter 键的 ListView 的情况下不起作用。出于某种原因,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 函数中的最后一个参数。这指定我们是否要处理已经由可视树中的前一个元素处理的事件。 当然不要忘记在适当的时候取消订阅活动

【讨论】:

  • 非常感谢您添加此答案!我完全忘记了这种技术,它解决了我的问题。我试图为 UWP 按钮附加一个 KeyDown 处理程序以捕获 Enter 和 Space,并且不想在 Click 处理程序中处理它们(它会自动捕获 Enter 和 Space 键)。这绝对是这个问题的正确解决方案。
【解决方案2】:

这是一种方法:订阅全局 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"/>

【讨论】:

  • 谢谢!这解决了SpaceUpDown 的问题,但Enter 仍然没有触发。知道为什么吗?并不是说这是一个大问题,我可以没有 Enter 生活。也许还有其他一些事件触发了 Enter。
  • 注意:按照同样建议的正常方式为父 UI 对象添加事件处理程序将不起作用,因为事件是向上冒泡的,而不是向下冒泡的。我发现这个文档很详细,还描述了如何解决它msdn.microsoft.com/en-us/windows/uwp/xaml-platform/…
  • @Stephanie 最好在 OnNavigatedTo 或 OnLoaded 中订阅事件,当然记得在 OnNavigatedFrom 中取消订阅
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    你可以使用 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 2020-09-10
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多