كيفية إظهار قائمة السياق عند النقر بزر الماوس الأيمن فوق عنصر القائمة

StackOverflow https://stackoverflow.com/questions/281831

  •  07-07-2019
  •  | 
  •  

سؤال

أقوم بنقل تطبيق MFC إلى .NET WinForms.في تطبيق MFC، يمكنك النقر بزر الماوس الأيمن على القائمة أو على عنصر قائمة السياق ونعرض قائمة سياق أخرى تحتوي على عناصر التشخيص والتكوين.أحاول نقل هذه الوظيفة إلى .NET، ولكن أواجه مشكلة.

لقد تمكنت من التقاط النقر بزر الماوس الأيمن، وتعطيل النقر على القائمة الأساسية، وإظهار قائمة السياق في الموقع الصحيح، ولكن القائمة الأصلية تختفي بمجرد أن تفقد التركيز.

في MFC، نعرض قائمة السياق الجديدة عن طريق الاتصال TrackPopupMenuEx مع ال TPM_RECURSE علَم.

قائمة السياق والأحدث TextMenuStrip تحتوي الفئات في .NET فقط على يعرض طريقة.هل يعرف أحد كيفية القيام بذلك في .NET؟

يحرر

لقد حاولت استخدام TrackPopupMenuEx من خلال p/invocation، ولكن هذا يحدك من استخدام contextMenu بدلاً من contextMenuStrip الذي يبدو في غير مكانه في تطبيقنا.كما أنه لا يزال لا يعمل بشكل صحيح.لا يعمل مع الجديد MenuStrip و TextMenuStrip.

لقد حاولت أيضًا إنشاء فئة فرعية لـ ToolStripMenuItem لمعرفة ما إذا كان بإمكاني إضافة قائمة سياق إليها.هذا يعمل من أجل MenuStrip, ، لكن TextMenuStrip لا يزال يسمح لأحداث النقر بزر الماوس الأيمن بالمرور كنقرات.

هل كانت مفيدة؟

المحلول

تعديل بسبب تعليق:

في:

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

هذا الجزء

 MouseButtons != MouseButtons.Right

يجب أن يتم تجميعه لأنه عبارة عن استدعاء لـ Control.MouseButtons.بما أن النموذج يرث فئة التحكم، فإنه يكفي استدعاء خاصية 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;
    }
}

نصائح أخرى

ربما سيتعين عليك p/استدعاء الطريقة.

[DllImport("user32.dll")]
static extern bool TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y,
IntPtr hwnd, IntPtr lptpm);

const int TPM_RECURSE = 0x0001; 

يوضح هذا كيفية استخدام قوائم السياق المتعددة بالإضافة إلى قوائم مختلفة مع أي مجموعة من نقرات الماوس.

المزيد هنا: http://code.msdn.microsoft.com/TheNotifyIconExample

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top