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

如何在MAUI.NET控件中添加而非重定义上下文菜单项

在.NET MAUI Entry控件中添加自定义上下文菜单项而不覆盖默认菜单

问题描述

我按照官方教程给Entry控件实现了上下文菜单,代码如下:

<Entry ...>
    <FlyoutBase.ContextFlyout>
        <MenuFlyout>
            <MenuFlyoutItem Text="..." Command="..." CommandParameter="..." />
        </MenuFlyout>
    </FlyoutBase.ContextFlyout>
</Entry>

菜单能正常工作,但Entry自带的复制、粘贴等默认上下文菜单项被完全覆盖了。想找一个无需重写默认行为的简便方法,把自定义菜单项插入到默认菜单列表中。


解决方案

方法1:通过平台特定渲染器扩展默认菜单

Entry的默认上下文菜单由各平台原生控件提供,直接替换ContextFlyout会覆盖原生菜单,因此需要通过平台特定代码获取原生菜单并追加自定义项:

Android平台实现

在Android项目中创建自定义Entry渲染器:

using Android.Content;
using Android.Views;
using Microsoft.Maui.Controls.Platform;

[assembly: ExportRenderer(typeof(Entry), typeof(CustomEntryRenderer))]
namespace YourAppNamespace.Droid
{
    public class CustomEntryRenderer : EntryRenderer
    {
        public CustomEntryRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control.CustomSelectionActionModeCallback = new CustomActionCallback(Control);
            }
        }

        private class CustomActionCallback : Java.Lang.Object, ActionMode.ICallback
        {
            private readonly Android.Widget.EditText _editText;

            public CustomActionCallback(Android.Widget.EditText editText)
            {
                _editText = editText;
            }

            public bool OnCreateActionMode(ActionMode mode, IMenu menu)
            {
                // 保留默认菜单项
                _editText.CreateActionMode(mode, menu);
                // 追加自定义菜单项
                var customItem = menu.Add("自定义操作");
                customItem.SetOnMenuItemClickListener(new CustomMenuItemClickListener(_editText, mode));
                return true;
            }

            public bool OnPrepareActionMode(ActionMode mode, IMenu menu) => false;

            public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
            {
                if (item.TitleFormatted.ToString() == "自定义操作")
                {
                    // 执行自定义逻辑,可绑定ViewModel命令
                    var entry = _editText.Tag as Entry;
                    (entry.BindingContext as YourViewModel)?.CustomCommand.Execute(null);
                    mode.Finish();
                    return true;
                }
                return false;
            }

            public void OnDestroyActionMode(ActionMode mode) { }
        }

        private class CustomMenuItemClickListener : Java.Lang.Object, IMenuItemOnMenuItemClickListener
        {
            private readonly Android.Widget.EditText _editText;
            private readonly ActionMode _actionMode;

            public CustomMenuItemClickListener(Android.Widget.EditText editText, ActionMode actionMode)
            {
                _editText = editText;
                _actionMode = actionMode;
            }

            public bool OnMenuItemClick(IMenuItem item) => true;
        }
    }
}

iOS平台实现

在iOS项目中创建自定义Entry渲染器:

using UIKit;
using Microsoft.Maui.Controls.Platform;

[assembly: ExportRenderer(typeof(Entry), typeof(CustomEntryRenderer))]
namespace YourAppNamespace.iOS
{
    public class CustomEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control.ShouldShowMenu = (textField) =>
                {
                    // 获取默认菜单并追加自定义项
                    var defaultMenu = textField.ShouldShowMenu();
                    if (defaultMenu != null)
                    {
                        var customItem = new UIMenuItem("自定义操作", new ObjCRuntime.Selector("HandleCustomAction:"));
                        defaultMenu.AddItem(customItem);
                    }
                    return true;
                };

                // 绑定自定义操作的处理方法
                Control.AddTarget(HandleCustomAction, UIControlEvent.MenuActionTriggered, new ObjCRuntime.Selector("HandleCustomAction:"));
            }
        }

        [ObjCRuntime.Export("HandleCustomAction:")]
        void HandleCustomAction(UIMenuItem sender)
        {
            // 执行自定义逻辑,可绑定ViewModel命令
            var entry = Element as Entry;
            (entry.BindingContext as YourViewModel)?.CustomCommand.Execute(null);
        }
    }
}

方法2:利用MAUI Community Toolkit扩展

如果项目已引入MAUI Community Toolkit,可以使用其提供的上下文菜单扩展方法,直接在默认菜单基础上追加自定义项,无需编写原生渲染器代码(需注意版本兼容性)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:23:30