The problem is that I cannot get the item on which the context menu was displayed.
For this problem, if you add data to the ListView as follows:
<ListView RightTapped="ListView_RightTapped"> <x:String>First Item</x:String> <x:String>Second Item</x:String> <x:String>Third Item</x:String> <x:String>Fourth Item</x:String> <ListView.Resources> <MenuFlyout x:Name="allContactsMenuFlyout"> <MenuFlyout.Items> <MenuFlyoutItem x:Name="Edit" Text="Edit" /> <MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click" /> </MenuFlyout.Items> </MenuFlyout> </ListView.Resources> </ListView>
You can get the context of the element in the RightTapped event as follows:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e) { ListView listView = (ListView)sender; allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView)); var a = ((FrameworkElement)e.OriginalSource).DataContext; }
In this case, "a" will directly receive the contents of the string format with the item pressed.
If you add your data to a ListView using a DataTemplate as follows:
<ListView RightTapped="ListView_RightTapped" ItemsSource="{x:Bind list}"> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding text}" /> </DataTemplate> </ListView.ItemTemplate> <ListView.Resources> <MenuFlyout x:Name="allContactsMenuFlyout"> <MenuFlyout.Items> <MenuFlyoutItem x:Name="Edit" Text="Edit" /> <MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click" /> </MenuFlyout.Items> </MenuFlyout> </ListView.Resources> </ListView>
and usually when using a DataTemplate we add ObservableCollection data as follows:
private ObservableCollection<List> list = new ObservableCollection<List>(); public MainPage() { this.InitializeComponent(); list.Clear(); list.Add(new List { text = "Item 1" }); list.Add(new List { text = "Item 2" }); list.Add(new List { text = "Item 3" }); list.Add(new List { text = "Item 4" }); list.Add(new List { text = "Item 5" }); }
The "list" class is pretty simple for the test:
public class List { public string text { get; set; } }
Then we can also get the DataContext in the RightTapped event:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e) { ListView listView = (ListView)sender; allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView)); var a = ((FrameworkElement)e.OriginalSource).DataContext; }
But this time, โaโ is actually a โListโ object (see the โListโ class) inside an element, because the contents of the element are now a โListโ object, not a string. Therefore, we can get the text property of this object as follows way:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e) { ListView listView = (ListView)sender; allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView)); var a = ((FrameworkElement)e.OriginalSource).DataContext as List; var content = a.text; }
I think that in the end you will want to edit the content in the click Button Flyout , you can do this, for example, as follows:
private string content; private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e) { ListView listView = (ListView)sender; allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView)); var a = ((FrameworkElement)e.OriginalSource).DataContext as List; content = a.text; } private void Remove_Click(object sender, RoutedEventArgs e) { foreach (var item in list.ToList()) { if (item.text == content) { list.Remove(item); } } content = ""; }
Another problem is that the context menu is also displayed outside the list item (for example, at borders).
Can you explain this? I canโt figure it out. Do you mean displaying content, for example, in Flyout ? If so, I think the method above can solve this problem. If not, you can leave a comment and I will see if this problem can be solved.
And since the triggered event is RightTapped, I'm not sure if the context menu will be displayed when the mobile devices are pressed for a long time.
I think the โlong clickโ event here denotes a Holding event like this?
private void ListView_Holding(object sender, HoldingRoutedEventArgs e) { ListView listView = (ListView)sender; allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView)); var a = ((FrameworkElement)e.OriginalSource).DataContext as List; content = a.text; }
I just test it on Mobile Emulator, it works great. Although I wrote a rather long answer here, but the key point is quite simple, you can simply use ((FrameworkElement)e.OriginalSource).DataContext to get the context of the element.