Question

In a Windows Forms app I set the ContextMenuStrip property on a TabControl.

  1. How can I tell the user clicked a tab other then the one that is currently selected?
  2. How can I restrict the context menu from showing only when the top Tab portion with the label is clicked, and not elsewhere in the tab?
Was it helpful?

Solution

Don't bother setting the contextMenuStrip property on the TabControl. Rather do it this way. Hook up to the tabControl's MouseClick event, and then manually show the context menu. This will only fire if the tab itself on top is clicked on, not the actual page. If you click on the page, then the tabControl doesn't receive the click event, the TabPage does. Some code:

public Form1()
{
    InitializeComponent();
    this.tabControl1.MouseClick += new MouseEventHandler(tabControl1_MouseClick);
}

private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        this.contextMenuStrip1.Show(this.tabControl1, e.Location);
    }


}

OTHER TIPS

Opening event of context menu can be used to solve both problems

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{            
    Point p = this.tabControl1.PointToClient(Cursor.Position);
    for (int i = 0; i < this.tabControl1.TabCount; i++)
    {
        Rectangle r = this.tabControl1.GetTabRect(i);
        if (r.Contains(p))
        {
            this.tabControl1.SelectedIndex = i; // i is the index of tab under cursor
            return;
        }
    }
    e.Cancel = true;
}

A bit late, but I've found a solution for the first part of your question. You can figure out which tab was right-clicked on by sending a left mouse click to the application. This selects the tab, so now you can use the TabControl.SelectedTab property to get the tab that the user right-clicked on.

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

    private const int MOUSEEVENTF_LEFTDOWN = 0x02;
    private const int MOUSEEVENTF_LEFTUP = 0x04;
    private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
    private const int MOUSEEVENTF_RIGHTUP = 0x10;

    private static void SendLeftMouseClick()
    {
        int x = Cursor.Position.X;
        int y = Cursor.Position.Y;
        mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, x, y, 0, 0);
    }

    public Form1()
    {
        InitializeComponent();

        tabControl1.MouseDown += new MouseEventHandler(tabControl1_MouseDown);
        tabControl1.MouseUp += new MouseEventHandler(tabControl1_MouseUp);
    }

    void tabControl1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            // Send a left mouse click to select the tab that the user clicked on.
            SendLeftMouseClick();
        }
    }

    void tabControl1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            // To show a context menu for only the tab button but not the content of the tab,
            // we must show it in the tab control's mouse up event.
            contextMenuStrip1.Show((Control)sender, e.Location);
        }
    }

I was looking for a solution for the exact same problem.
After testing both @nisar and @BFree answers I came to this (I also had the TabControl` inside a Panel somewhere in the Form):

  • Create tabcontrol1
  • Subscribe to the MouseClick event
  • Create contextMenuTabs, ContextMenuStrip


private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        Point ee = new Point(e.Location.X - panel1.Left, e.Location.Y - panel1.Top);
        for (int i = 0; i < this.tabControl1.TabCount; i++)
        {
            Rectangle r = this.tabControl1GetTabRect(i);
            if (r.Contains(ee))
            {
                if (this.tabControl1.SelectedIndex == i)
                    this.contextMenuTabs.Show(this.tabControl1, e.Location);
                else 
                    {
                      //if a non seelcted page was clicked we detected it here!!
                    }

                break;
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top