Pregunta

En una aplicación de Windows Forms configuro la propiedad ContextMenuStrip en un TabControl.

  1. ¿Cómo puedo saber si el usuario hizo clic en una pestaña distinta de la que está seleccionada actualmente?
  2. ¿Cómo puedo restringir que el menú contextual se muestre solo cuando se hace clic en la parte superior de la pestaña con la etiqueta, y no en otra parte de la pestaña?
¿Fue útil?

Solución

No te molestes en configurar la propiedad contextMenuStrip en TabControl. Más bien hazlo de esta manera. Conéctese al evento MouseClick de tabControl y luego muestre manualmente el menú contextual. Esto solo se activará si se hace clic en la pestaña en la parte superior, no en la página real. Si hace clic en la página, entonces tabControl no recibe el evento click, TabPage sí. Algún código:

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


}

Otros consejos

El evento de apertura del menú contextual se puede utilizar para resolver ambos problemas

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

Un poco tarde, pero he encontrado una solución para la primera parte de su pregunta. Puede averiguar en qué pestaña se hizo clic con el botón derecho del mouse enviando un clic izquierdo a la aplicación. Esto selecciona la pestaña, por lo que ahora puede usar la propiedad TabControl.SelectedTab para obtener la pestaña en la que el usuario hizo clic con el botón derecho.

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

Estaba buscando una solución para exactamente el mismo problema.
Después de probar las respuestas @nisar y @BFree llegué a esto (también tenía el TabControl` dentro de un Panel en algún lugar del Formulario):

  • Crear tabcontrol1
  • Suscríbete al evento MouseClick
  • Crear 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;
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top