You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中基于CollectionView实现在安卓、iOS长按打开菜单选项

在.NET MAUI中实现CollectionView元素长按弹出菜单功能

完全可以实现,针对安卓和iOS平台,推荐两种方案:原生ContextMenu适配(符合系统交互规范)、自定义长按弹窗(支持高度定制),以下是具体实现步骤:

方案一:使用.NET MAUI原生ContextMenu(推荐)

直接利用MAUI内置的ContextMenu控件,自动适配安卓和iOS的原生菜单样式,代码简洁且符合系统交互习惯。

XAML代码示例

<CollectionView ItemsSource="{Binding YourItemList}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <!-- 用Frame作为Item容器,确保手势可触发 -->
            <Frame Padding="12" Margin="6" CornerRadius="8">
                <Label Text="{Binding ItemName}" FontSize="16" />
                
                <!-- 绑定长按菜单 -->
                <Frame.ContextMenu>
                    <ContextMenu>
                        <MenuItem Text="复制" 
                                  Clicked="CopyItem_Clicked" 
                                  CommandParameter="{Binding .}" />
                        <MenuItem Text="删除" 
                                  Clicked="DeleteItem_Clicked" 
                                  CommandParameter="{Binding .}" />
                        <MenuItem Text="分享" 
                                  Clicked="ShareItem_Clicked" 
                                  CommandParameter="{Binding .}" />
                    </ContextMenu>
                </Frame.ContextMenu>
            </Frame>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

后台事件处理代码

private void CopyItem_Clicked(object sender, EventArgs e)
{
    if (sender is MenuItem menuItem && menuItem.CommandParameter is YourItemModel item)
    {
        // 执行复制逻辑
        _ = Clipboard.SetTextAsync(item.ItemName);
    }
}

private void DeleteItem_Clicked(object sender, EventArgs e)
{
    if (sender is MenuItem menuItem && menuItem.CommandParameter is YourItemModel item)
    {
        // 执行删除逻辑(需绑定ViewModel的集合)
        YourViewModel.ItemList.Remove(item);
    }
}

方案二:自定义长按弹窗(高度定制)

如果需要完全自定义菜单样式,可以结合LongPressGestureRecognizer和CommunityToolkit.Maui的Popup控件实现。

步骤1:安装依赖包

在项目中安装CommunityToolkit.Maui NuGet包,并在MauiProgram.cs中注册:

builder.UseMauiApp<App>().UseMauiCommunityToolkit();

步骤2:XAML中绑定长按手势

<CollectionView ItemsSource="{Binding YourItemList}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Frame Padding="12" Margin="6" CornerRadius="8">
                <Label Text="{Binding ItemName}" FontSize="16" />
                
                <!-- 添加长按手势 -->
                <Frame.GestureRecognizers>
                    <LongPressGestureRecognizer 
                        Command="{Binding Source={RelativeSource AncestorType={x:Type local:YourViewModel}}, Path=LongPressCommand}"
                        CommandParameter="{Binding .}" />
                </Frame.GestureRecognizers>
            </Frame>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

步骤3:ViewModel中实现命令

public ICommand LongPressCommand { get; }

public YourViewModel()
{
    LongPressCommand = new Command<YourItemModel>(async (item) =>
    {
        // 弹出自定义菜单弹窗
        var actionPopup = new ItemActionPopup(item);
        await Application.Current.MainPage.ShowPopupAsync(actionPopup);
    });
}

步骤4:创建自定义弹窗

<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="YourApp.Views.ItemActionPopup"
             Size="220, 180"
             Anchor="{Binding Source={RelativeSource AncestorType={x:Type Frame}}}">
    <VerticalStackLayout Spacing="8" Padding="12">
        <Button Text="复制" Clicked="Copy_Clicked" StyleClass="PopupButton" />
        <Button Text="删除" Clicked="Delete_Clicked" StyleClass="PopupButton" />
        <Button Text="分享" Clicked="Share_Clicked" StyleClass="PopupButton" />
    </VerticalStackLayout>
</toolkit:Popup>
public partial class ItemActionPopup : Popup
{
    private readonly YourItemModel _currentItem;

    public ItemActionPopup(YourItemModel item)
    {
        InitializeComponent();
        _currentItem = item;
    }

    private async void Copy_Clicked(object sender, EventArgs e)
    {
        await Clipboard.SetTextAsync(_currentItem.ItemName);
        await CloseAsync();
    }

    private async void Delete_Clicked(object sender, EventArgs e)
    {
        // 通过弱引用信使通知ViewModel删除(避免强引用)
        WeakReferenceMessenger.Default.Send(new DeleteItemMessage(_currentItem));
        await CloseAsync();
    }
}

适配注意事项

  • 原生ContextMenu方案:iOS会弹出系统样式的菜单,安卓则显示底部/侧边菜单,完全贴合平台交互习惯
  • 自定义弹窗方案:可通过Anchor属性绑定触发长按的元素,让菜单精准显示在元素附近
  • 确保CollectionView的Item容器(如Frame、ContentView)可交互,避免直接在纯文本控件上绑定手势

内容的提问来源于stack exchange,提问作者Ajay Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 21:05:17