Reputation: 37
In this question UWP: how to get the RightTapped GridView Item , there is a way to get the "right clicked" item in GridView (in UWP, GridView is almost the same as ListView):
var student = (e.OriginalSource as FrameworkElement)?.DataContext as Student;
The ?.
symbol is interesting because when you right clicked on an item using mouse, this is OK. But when you "righttapped" an item using the Menu Button (https://en.wikipedia.org/wiki/Menu_key) or using the Menu Button on Xbox Controller, this is NOT ok because the value is null (actually the type of OriginalSource is GridViewItem).
Though I have found a solution:
(((GridViewItem)e.OriginalSource).Content as YOUR_ITEM_DATA_TYPE)
to handle menu button(e.OriginalSource as FrameworkElement)?.DataContext as YOUR_ITEM_DATA_TYPE
to handle mouse right clicktypeof(e.OriginalSource)
can be used with if...else... to choose which solution to use.
But is this the real best solution? Microsoft designed UWP and said it is optimized to handle mouse, keyboard, gamepad such as Xbox controller and even eye tracker seamlessly. So are there a better way to handle the "context menu" (https://learn.microsoft.com/en-us/windows/uwp/design/input/gamepad-and-remote-interactions#accelerator-support) action?
My target:
left click an item → do something about itemlist[clicked index]
right click an item → open a menu such as edit, delete → click edit → do something about itemlist[right clicked index]
PS: Try "Settings" in Windows 10, it works fine to "right click" an item (to pin a tile in start menu) using mouse , keyboard or Xbox Controller
Upvotes: 2
Views: 243
Reputation: 32785
The ?. symbol is interesting because when you right clicked on an item using mouse, this is OK. But when you "righttapped" an item using the Menu Button (https://en.wikipedia.org/wiki/Menu_key) or using the Menu Button on Xbox Controller, this is NOT ok
e.OriginalSource
is different type when you right-click or press Menu.
Press Menu
e.OriginalSource
is ListViewItem
Right-click
e.OriginalSource
is ListViewItemPresenter
And that is why (ListViewItem)e.OriginalSource)
throw exception when right click listview item. But both Content and DataContext of ListViewItemPresenter
has value.
When you press Menu button, the matched e.OriginalSource
type is ListViewItem
, and the it's DataContext
is null.
And you could find some rules that ListViewItemPresenter
parent is ListViewItem
, and you could use the following code to find ListViewItemPresenter
parent when right-click the listview item and converter it to ListViewItem
.
When you click the menu button the OriginalSource is ListViewItem, and you could use it directly. I have tested the following method, it works well in right-click and menu-click model.
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);
}
}
Upvotes: 0