代码之家  ›  专栏  ›  技术社区  ›  blu

选项卡控件上下文菜单

  •  7
  • blu  · 技术社区  · 15 年前

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

    1. 如何告诉用户单击了当前选中的选项卡之外的其他选项卡?
    2. 如何限制上下文菜单仅在单击带有标签的顶部选项卡部分时显示,而不是在选项卡的其他位置显示?
    4 回复  |  直到 6 年前
        1
  •  12
  •   BFree    15 年前

    不要费心在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);
        }
    
    
    }
    
        2
  •  11
  •   nisar    12 年前

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

    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;
    }
    
        3
  •  2
  •   AJ_    13 年前

    有点晚了,但我已经为你问题的第一部分找到了解决办法。您可以通过向应用程序发送鼠标左键单击来确定右键单击了哪个选项卡。这将选择选项卡,因此现在可以使用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);
            }
        }
    
        4
  •  0
  •   Jimi    6 年前

    我在为同样的问题寻找解决办法。
    在测试了@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;
                }
            }
        }
    }