【问题标题】:UWP GridView/ListView get the RightTapped Item supporting both mouse and Xbox ControllerUWP GridView/ListView 获取同时支持鼠标和 Xbox 控制器的 RightTapped Item
【发布时间】:2020-11-02 19:08:05
【问题描述】:

在这个问题UWP: how to get the RightTapped GridView Item 中,有一种方法可以在GridView中获取“右键单击”项(在UWP中,GridView与ListView几乎相同):

var student = (e.OriginalSource as FrameworkElement)?.DataContext as Student;

?. 符号很有趣,因为当您使用鼠标右键单击 on 一个项目时,就可以了。但是当您使用菜单按钮 (https://en.wikipedia.org/wiki/Menu_key) 或使用 Xbox 控制器上的菜单按钮“右键点击”项目时,这是 NOT 好的,因为该值为 null(实际上 OriginalSource 的类型是 GridViewItem )。

虽然我找到了解决办法:

  1. 使用(((GridViewItem)e.OriginalSource).Content as YOUR_ITEM_DATA_TYPE)处理菜单按钮
  2. 使用(e.OriginalSource as FrameworkElement)?.DataContext as YOUR_ITEM_DATA_TYPE处理鼠标右键

typeof(e.OriginalSource) 可以与 if...else... 一起使用以选择要使用的解决方案。

但这真的是最好的解决方案吗?微软设计了 UWP,并表示它已针对鼠标、键盘、Xbox 控制器等游戏手柄甚至眼动仪进行了优化。那么有没有更好的方法来处理“上下文菜单”(https://docs.microsoft.com/en-us/windows/uwp/design/input/gamepad-and-remote-interactions#accelerator-support)动作?

我的目标:

  • 左键单击一个项目→对项目列表做一些事情[点击索引]

  • 右键单击项目→打开编辑、删除等菜单→单击编辑→ 对 itemlist[右键单击索引] 做一些事情

PS:在 Windows 10 中尝试“设置”,使用鼠标、键盘或 Xbox 控制器“右键单击”项目(在开始菜单中固定磁贴)效果很好

【问题讨论】:

    标签: c# uwp


    【解决方案1】:

    ?.符号很有趣,因为当您使用鼠标右键单击某个项目时,这是可以的。但是,当您使用菜单按钮 (https://en.wikipedia.org/wiki/Menu_key) 或使用 Xbox 控制器上的菜单按钮“右键点击”项目时,这是不行的

    e.OriginalSource 是不同的类型,当您右键单击或按 Menu 时。

    菜单

    e.OriginalSourceListViewItem

    右击

    e.OriginalSourceListViewItemPresenter

    这就是为什么(ListViewItem)e.OriginalSource) 在右键单击列表视图项时抛出异常的原因。但是ListViewItemPresenterContentDataContext都有价值。

    当你按下Menu按钮时,匹配到的e.OriginalSource类型为ListViewItem,而它的DataContext为空。

    你会发现ListViewItemPresenter parent 是ListViewItem 的一些规则,你可以使用下面的代码找到ListViewItemPresenter parent,右键单击listview 项并将其转换为ListViewItem

    当你点击菜单按钮时,OriginalSource 是 ListViewItem,你可以直接使用它。下面的方法我已经测试过了,在右键和菜单点击模式下效果很好。

    private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
    {
        var orig = e.OriginalSource as DependencyObject;
    
        while (orig != null && orig != MyListView)
        {
            var lv = orig as ListViewItem;
            if (lv != null)
            {
                var res1 = (lv.Content as string); //string is an example of data binding type of ListViewItem
                //This line will run only if right-tapped on an item, do something here
                break;
            }
    
            orig = VisualTreeHelper.GetParent(orig);
    
        }
    }
    

    【讨论】:

    • 不错!这解决了所有可能性: 1. 在列表视图中右键单击,但没有在任何项目中单击将运行到最后一行。 2.使用鼠标或菜单按钮或Xbox控制器右键单击时,在break之前做一些事情;
    猜你喜欢
    • 2017-05-02
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    相关资源
    最近更新 更多