divB
divB

Reputation: 973

ToolStripMenuItem: Add arrow without submenu

How can I add a menu item that has an arrow to the right as if there would be a submenu but does not show a submenu?

Background: For a managed C# application I want to add a submenu which is created in an unmanaged DLL (using TrackPopupMenu()).

In my experiments, I can only show the arrow when there are items attached using "DropDownItems.Add".

I tried to use

ToolStripMenuItem menu = new ToolStripMenuItem();
m_menu.Text = "Item that should have arrow w/o submenu";
m_menu.Click += this.OnMenuDoSomething;
m_menu.DropDownItems.Add("");

This still adds a submenu. I then tried these combinations:

m_menu.DropDownItems[0].Enabled = false;
m_menu.DropDownItems[0].Available = false;
m_menu.DropDownItems[0].Visible = false;

but either the submenu including the arrow disappears or nothing at all.

Upvotes: 0

Views: 1245

Answers (1)

Loathing
Loathing

Reputation: 5266

When the drop down menu's handle is created, assign it to a NativeWindow to capture the window messages and hide the paint events. In fact, you can hide all events.

When you want to show the drop down menu, simply release the NativeWindow's handle.

E.g.

    private class NW : NativeWindow {
        public NW(IntPtr handle) {
            AssignHandle(handle);
        }

        const int WM_PAINT = 0xF;
        protected override void WndProc(ref Message m) {
            // can ignore all messages too
            if (m.Msg == WM_PAINT) {
                return;
            }
            base.WndProc(ref m);
        }
    }

    [STAThread]
    static void Main() {

        MenuStrip menu = new MenuStrip();

        NW nw = null; // declared outside to prevent garbage collection
        ToolStripMenuItem item1 = new ToolStripMenuItem("Item1");
        ToolStripMenuItem subItem1 = new ToolStripMenuItem("Sub Item1");
        subItem1.DropDown.DropShadowEnabled = false;
        subItem1.DropDown.HandleCreated += delegate {
            nw = new NW(subItem1.DropDown.Handle);
        };

        ToolStripMenuItem miMakeVisible = new ToolStripMenuItem("Make Visible");
        miMakeVisible.Click += delegate {
            if (nw != null) {
                nw.ReleaseHandle();
                nw = null;
            }
        };


        ToolStripMenuItem subItem2 = new ToolStripMenuItem("Sub Item2");
        item1.DropDownItems.Add(subItem1);
        item1.DropDownItems.Add(miMakeVisible);
        subItem1.DropDownItems.Add(subItem2);
        menu.Items.Add(item1);


        Form f = new Form();
        f.Controls.Add(menu);
        f.MainMenuStrip = menu;
        Application.Run(f);
    }

Upvotes: 1

Related Questions