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

.NET MAUI ListView项的直观上下文菜单实现方案咨询

.NET MAUI ListView项的直观上下文菜单实现方案咨询

嘿,我正好折腾过类似的需求!你的这个场景完全可以用MAUI自带的功能组合出来,不用非得找百分百开箱即用的组件,我给你梳理个清晰的实现思路:

核心思路

把不同平台的触发逻辑拆分处理,然后复用同一个自定义上下文菜单,这样就能同时满足汉堡按钮、Windows右键、iOS/Android长按+保留点击跳转的所有需求,效果完全能做到像Spotify那样。


具体实现步骤

1. 先给ListView项加个汉堡按钮

在你的ListView的ItemTemplate里,给每个项的右侧加个汉堡按钮(用MAUI自带的FontImageSource或者你项目里的图标都行),点击按钮就弹出自定义菜单:

<DataTemplate x:Key="CustomListViewItemTemplate">
    <Grid Padding="8" ColumnDefinitions="*,Auto">
        <!-- 这里放你原来的项内容,比如标题、封面图这些 -->
        <Label Grid.Column="0" Text="{Binding ItemTitle}" VerticalOptions="Center" />
        <!-- 汉堡按钮,固定在右侧 -->
        <Button Grid.Column="1"
                ImageSource="hamburger_icon"
                WidthRequest="40"
                Clicked="HamburgerMenu_Clicked" />
    </Grid>
</DataTemplate>

代码后台里,点击按钮的事件直接调用菜单显示逻辑就行,后面所有场景都会复用这个逻辑。

2. Windows平台:绑定右键触发

给ListView项加个自定义行为,专门处理Windows的右键点击:

public class WinRightClickBehavior : Behavior<ViewCell>
{
    protected override void OnAttachedTo(ViewCell bindable)
    {
        base.OnAttachedTo(bindable);
#if WINDOWS
        var nativeCell = bindable.Handler.PlatformView as Microsoft.UI.Xaml.Controls.ListViewItem;
        nativeCell.RightTapped += OnRightTapped;
#endif
    }

    private void OnRightTapped(object sender, Microsoft.UI.Xaml.Input.RightTappedRoutedEventArgs e)
    {
        // 复用统一的菜单显示方法
        ShowContextMenu((sender as Microsoft.UI.Xaml.Controls.ListViewItem).DataContext);
    }

    protected override void OnDetachingFrom(ViewCell bindable)
    {
#if WINDOWS
        var nativeCell = bindable.Handler.PlatformView as Microsoft.UI.Xaml.Controls.ListViewItem;
        nativeCell.RightTapped -= OnRightTapped;
#endif
        base.OnDetachingFrom(bindable);
    }
}

然后把这个行为加到ViewCell里:

<ViewCell>
    <ViewCell.Behaviors>
        <local:WinRightClickBehavior />
        <!-- 后面还要加长按的行为 -->
    </ViewCell.Behaviors>
    <!-- 项内容就是上面的Grid -->
</ViewCell>

3. iOS/Android平台:长按触发,保留点击跳转

再做个处理长按的行为,关键是不要拦截普通点击事件:

public class MobileLongPressBehavior : Behavior<ViewCell>
{
    protected override void OnAttachedTo(ViewCell bindable)
    {
        base.OnAttachedTo(bindable);
#if ANDROID
        var nativeCell = bindable.Handler.PlatformView as Android.Views.View;
        nativeCell.LongClick += OnLongClick;
#elif IOS
        var nativeCell = bindable.Handler.PlatformView as UIKit.UITableViewCell;
        var longPressGesture = new UIKit.UILongPressGestureRecognizer(OnLongPressTriggered);
        nativeCell.AddGestureRecognizer(longPressGesture);
#endif
    }

#if ANDROID
    private void OnLongClick(object sender, Android.Views.View.LongClickEventArgs e)
    {
        e.Handled = false; // 关键!不标记为已处理,普通点击依然能触发跳转
        ShowContextMenu((sender as Android.Views.View).BindingContext);
    }
#elif IOS
    private void OnLongPressTriggered(UIKit.UILongPressGestureRecognizer sender)
    {
        if (sender.State == UIKit.UIGestureRecognizerState.Began)
        {
            ShowContextMenu((sender.View as UIKit.UITableViewCell).BindingContext);
        }
    }
#endif

    // 和汉堡按钮、右键复用同一个菜单显示方法
    private void ShowContextMenu(object itemData)
    {
        // 弹出我们自定义的菜单弹窗
        var menuPopup = new ContextMenuPopup();
        menuPopup.BindingContext = itemData;
        Application.Current.MainPage.ShowPopup(menuPopup);
    }
}

把这个行为也加到ViewCell里,这样iOS/Android上长按就弹菜单,点一下还是正常跳详情页。

4. 统一的自定义上下文菜单:用Popup实现

MAUI的Popup是跨平台的,自定义一个Popup当菜单,里面放编辑、删除、添加子项这些操作按钮,绑定对应的命令就行:

<maui:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="YourApp.Views.ContextMenuPopup"
             Size="220, 320"
             BackgroundColor="White"
             CornerRadius="8">
    <VerticalStackLayout Padding="12" Spacing="10">
        <Button Text="编辑" Command="{Binding EditCommand}" HorizontalOptions="Fill" />
        <Button Text="删除" Command="{Binding DeleteCommand}" HorizontalOptions="Fill" />
        <Button Text="添加子项" Command="{Binding AddChildCommand}" HorizontalOptions="Fill" />
    </VerticalStackLayout>
</maui:Popup>

这个Popup的样式你可以随便调,完全能做到和Spotify的菜单一样的效果。


额外小提示

  • 你也可以把Windows右键和移动端长按的行为合并成一个,用编译符号区分平台逻辑,代码会更整洁。
  • ListView的ItemSelected事件正常处理详情页跳转就行,和所有菜单触发逻辑完全独立,不会冲突。
  • 要是不想用Popup,也可以用MAUI的MenuFlyout,但Popup的自定义程度更高,更容易做出你想要的样式。

这个方案完全是基于MAUI自带的控件和功能实现的,不用加任何第三方库,调试起来也简单,绝对能满足你所有的需求!

备注:内容来源于stack exchange,提问作者Kai Fröhlich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 08:07:58