UWP ListView项目上下文菜单

mis*_*hut 7 xaml contextmenu win-universal-app

我在网上搜索如何添加上下文菜单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) {

}
Run Code Online (Sandbox Code Playgroud)

问题是我无法获得显示上下文菜单的项目.另一个问题是上下文菜单也显示在列表视图项之外(例如,在边框上).由于触发的事件是RightTapped,我不确定是否会在长按移动设备上显示上下文菜单.我无法测试它,因为我的模拟器当前不工作.因为它应该是通用的Windows应用程序,我期待一些非常简单有效的方法为ListView项目创建上下文菜单.

Gra*_*eng 15

问题是我无法获得显示上下文菜单的项目.

对于此问题,如果您将数据添加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>
Run Code Online (Sandbox Code Playgroud)

您可以在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;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,"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>
Run Code Online (Sandbox Code Playgroud)

通常在使用时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" });
}
Run Code Online (Sandbox Code Playgroud)

"List"类在这里测试非常简单:

public class List
{
    public string text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我们也可以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;
}
Run Code Online (Sandbox Code Playgroud)

但这一次,"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;
}
Run Code Online (Sandbox Code Playgroud)

我想最终你想编辑Button Click事件中的内容Flyout,你可以这样做,例如:

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 = "";
}
Run Code Online (Sandbox Code Playgroud)

另一个问题是上下文菜单也显示在列表视图项之外(例如,在边框上).

你能解释一下吗?我不太明白.你的意思是显示内容,例如在Flyout?如果是这样,我认为上面的方法可以解决这个问题.如果没有,你可以发表评论,我会看看是否可以解决这个问题.

由于触发的事件是RightTapped,我不确定是否会在长按移动设备上显示上下文菜单.

我认为这里的"长按"事件表明这样的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;
}
Run Code Online (Sandbox Code Playgroud)

我只是在移动模拟器上测试它,它工作正常.虽然我在这里写了一个很长的答案,但关键点很简单,你可以((FrameworkElement)e.OriginalSource).DataContext用来获取项目的Context.