xaml - UWP ListView项目上下文菜单

标签 xaml win-universal-app contextmenu

我正在搜索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/

相关文章:

c# - WPF 设计器无法加载

c# - UWP、MySQL、填充ListView、实现CRUD操作

c# - 将多个文件/文件夹从 Windows 资源管理器传递到外部应用程序

javascript - 右键单击文本框创建菜单和操作

c# - 使用 Mono 的跨平台 C# 应用程序和漂亮的 UI

c# - 帮助注册附加依赖属性

iis - 无法访问http ://localhost after sideloading

Angular 2右键单击事件?

c# - 如何在 wpf 中制作多色分段进度条?

c# - 使用StorageFile来获取位图尺寸,然后再使用它来读取图像?