微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 当您右键单击菜单项时如何显示上下文菜单

我正在将一个MFC应用程序移植到.NET WinForms.在MFC应用程序中,您可以右键单击菜单或上下文菜单项,并显示一个包含诊断和配置项的上下文菜单.我试图将这个功能移植到.NET,但是我遇到麻烦.

我已经能够捕获右键单击,禁用基本菜单的点击并弹出正确位置的上下文菜单,但是原始菜单会在失去焦点后立即消失.

在MFC中,通过使用TPM_RECURSE标志调用TrackPopupMenuEx来显示新的上下文菜单.

ContextMenu和.NET中的新的ContextMenuStrip类只有一个Show方法.有人知道如何在.NET中执行此操作?

编辑

我已经尝试通过p / invoke使用TrackPopupMenuEx,但是这限制了您使用ContextMenu而不是在我们的应用程序中不合适的ContextMenuStrip.它仍然不能正常工作.它不适用于新的MenuStrip和ContextMenuStrip.

我也尝试过子类化ToolStripMenuItem,看看我是否可以添加一个上下文菜单.这是为MenuStrip工作,但ContextMenuStrip仍然允许右键单击事件通过点击.

解决方法

编辑,由于评论

在:

protected override void OnClick(EventArgs e)
{
    if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right)
    {
        base.OnClick(e);
    }
}

这部分

MouseButtons != MouseButtons.Right

应该和确实编译,因为它是一个调用Control.MouseButtons.由于Form继承Control类,所以直接调用MouseButtons属性就足够了.

希望这可以帮助:

public partial class Form1 : Form
{
    class CustomToolStripMenuItem : ToolStripMenuItem
    {
        private ContextMenuStrip secondaryContextMenu;

        public ContextMenuStrip SecondaryContextMenu
        {
            get
            {
                return secondaryContextMenu;
            }
            set
            {
                secondaryContextMenu = value;
            }
        }

        public CustomToolStripMenuItem(string text)
            : base(text)
        { }

        protected override void dispose(bool disposing)
        {
            if (disposing)
            {
                if (secondaryContextMenu != null)
                {
                    secondaryContextMenu.dispose();
                    secondaryContextMenu = null;
                }
            }

            base.dispose(disposing);
        }

        protected override void OnClick(EventArgs e)
        {
            if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right)
            {
                base.OnClick(e);
            }
        }
    }

    class CustomContextMenuStrip : ContextMenuStrip
    {
        private bool secondaryContextMenuActive = false;
        private ContextMenuStrip lastShownSecondaryContextMenu = null;

        protected override void dispose(bool disposing)
        {
            if (disposing)
            {
                if (lastShownSecondaryContextMenu != null)
                {
                    lastShownSecondaryContextMenu.Close();
                    lastShownSecondaryContextMenu = null;
                }
            }
            base.dispose(disposing);
        }

        protected override void OnControlAdded(ControlEventArgs e)
        {
            e.Control.MouseClick += new MouseEventHandler(Control_MouseClick);
            base.OnControlAdded(e);
        }

        protected override void OnControlRemoved(ControlEventArgs e)
        {
            e.Control.MouseClick -= new MouseEventHandler(Control_MouseClick);
            base.OnControlRemoved(e);
        }

        private void Control_MouseClick(object sender,MouseEventArgs e)
        {
            ShowSecondaryContextMenu(e);
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            ShowSecondaryContextMenu(e);
            base.OnMouseClick(e);
        }

        private bool ShowSecondaryContextMenu(MouseEventArgs e)
        {
            CustomToolStripMenuItem ctsm = this.GetItemAt(e.Location) as CustomToolStripMenuItem;

            if (ctsm == null || ctsm.SecondaryContextMenu == null || e.Button != MouseButtons.Right)
            {
                return false;
            }

            lastShownSecondaryContextMenu = ctsm.SecondaryContextMenu;
            secondaryContextMenuActive = true;
            ctsm.SecondaryContextMenu.Closed += new toolstripdropdownClosedEventHandler(SecondaryContextMenu_Closed);
            ctsm.SecondaryContextMenu.Show(Cursor.Position);
            return true;
        }

        void SecondaryContextMenu_Closed(object sender,toolstripdropdownClosedEventArgs e)
        {
            ((ContextMenuStrip)sender).Closed -= new toolstripdropdownClosedEventHandler(SecondaryContextMenu_Closed);
            lastShownSecondaryContextMenu = null;
            secondaryContextMenuActive = false;
            Focus();
        }

        protected override void OnClosing(toolstripdropdownClosingEventArgs e)
        {
            if (secondaryContextMenuActive)
            {
                e.Cancel = true;
            }

            base.OnClosing(e);
        }
    }

    public Form1()
    {
        InitializeComponent();


        CustomToolStripMenuItem itemPrimary1 = new CustomToolStripMenuItem("item primary 1");
        itemPrimary1.SecondaryContextMenu = new ContextMenuStrip();
        itemPrimary1.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] { 
            new ToolStripMenuItem("item primary 1.1"),new ToolStripMenuItem("item primary 1.2"),});

        CustomToolStripMenuItem itemPrimary2 = new CustomToolStripMenuItem("item primary 2");
        itemPrimary2.DropDownItems.Add("item primary 2,sub 1");
        itemPrimary2.DropDownItems.Add("item primary 2,sub 2");
        itemPrimary2.SecondaryContextMenu = new ContextMenuStrip();
        itemPrimary2.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] { 
            new ToolStripMenuItem("item primary 2.1"),new ToolStripMenuItem("item primary 2.2"),});

        CustomContextMenuStrip primaryContextMenu = new CustomContextMenuStrip();
        primaryContextMenu.Items.AddRange(new ToolStripItem[]{
            itemPrimary1,itemPrimary2
        });

        this.ContextMenuStrip = primaryContextMenu;
    }
}

原文地址:https://www.jb51.cc/csharp/94655.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐