TabControl上下文菜单

时间:2009-01-19 14:10:43

标签: c# winforms tabcontrol contextmenu

在Windows窗体应用程序中,我在TabControl上设置了ContextMenuStrip属性。

  1. 如何告诉用户点击了当前选中的标签以外的标签?
  2. 如果仅在点击带有标签的顶部标签部分而不是标签中的其他位置时,我如何限制仅显示上下文菜单?

4 个答案:

答案 0 :(得分:12)

不要在TabControl上设置contextMenuStrip属性。而是这样做。连接到tabControl的MouseClick事件,然后手动显示上下文菜单。只有在单击选项卡本身时才会触发,而不是实际页面。如果单击该页面,则tabControl不会收到Click事件,TabPage会执行。一些代码:

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);
    }


}

答案 1 :(得分:11)

上下文菜单的开启事件可用于解决这两个问题

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;
}

答案 2 :(得分:2)

有点晚了,但我找到了问题第一部分的解决方案。您可以通过向应用程序发送鼠标左键来确定右键单击了哪个选项卡。这将选择选项卡,因此您现在可以使用TabControl.SelectedTab属性来获取用户右键单击的选项卡。

    [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);
        }
    }

答案 3 :(得分:0)

我正在为同样的问题寻找解决方案 在测试了@nisar和@BFree的答案后,我来到了这里(我在表格中的某个面板中也有TabControl`):

  • 创建tabcontrol1
  • 订阅MouseClick事件
  • 创建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;
            }
        }
    }
}