我正在搜索Internet,以了解如何为ListView
添加上下文菜单。到目前为止,我已经找到了一个真正显示上下文的
<ListView>
...
RightTapped="ContactsListView_RightTapped" >
...
<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>
private void ContactsListView_RightTapped(object sender, RightTappedRoutedEventArgs e) {
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
}
private void Remove_Click(object sender, RoutedEventArgs e) {
}
问题是我无法获得显示上下文菜单的项目。另一个问题是上下文菜单也显示在 ListView 项的外部(例如,在边框上)。并且由于触发的事件是RightTapped,因此我不确定是否会在长时间单击移动设备上显示上下文菜单。我无法测试它,因为我的仿真器当前无法正常工作。由于它应该是通用的Windows应用程序,因此我期待为ListView项目创建上下文菜单的一种非常简单有效的方法。
最佳答案
The problem is I'm not able to get item on which the context menu was displayed.
对于此问题,如果您将数据添加到
ListView
中,如下所示:<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>
您可以像这样在
RightTapped
事件中获取项目的上下文:private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext;
}
在这种情况下,“a”将直接获得单击项的字符串格式内容。
如果您使用
ListView
将数据添加到DataTemplate
中,如下所示:<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>
通常在使用
DataTemplate
时,我们通过ObservableCollection
添加数据,如下所示: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" });
}
“List”类在这里进行测试非常简单:
public class List
{
public string text { get; set; }
}
然后我们也可以在
DataContext
事件中获取RightTapped
:private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext;
}
但是这一次,“a”实际上是项目内部的“List”对象(请参阅“List”类),因为该项目的内容现在是“List”对象,不再是字符串。因此,我们可以像下面这样获取此对象的text属性:
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;
}
我认为最终您想编辑
Flyout
的Button click事件中的内容,您可以像这样进行操作: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 issue is that the context menu is displayed also outside of list view item (e.g. on borders).
你能解释一下吗?我不太明白。您是说要在
Flyout
中显示内容?如果是这样,我认为上述方法可以解决此问题。如果没有,您可以发表评论,我将看看是否可以解决此问题。And since the event that is triggered is RightTapped, I'm not sure if the context menu would be displayed on long click on mobile devices.
我认为这里的“长按”事件表示像这样的
Holding
事件?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;
}
我只是在Mobile Emulator上进行了测试,效果很好。尽管我在这里写了很长的答案,但是要点很简单,您可以只使用
((FrameworkElement)e.OriginalSource).DataContext
来获取项目的Context。
关于xaml - UWP ListView项目上下文菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36741757/