Domanda

In un'app di Windows Form ho impostato la proprietà ContextMenuStrip su un TabControl.

  1. Come posso dire all'utente di aver fatto clic su una scheda diversa da quella attualmente selezionata?
  2. Come posso impedire che il menu di scelta rapida venga visualizzato solo quando si fa clic sulla parte superiore della scheda con l'etichetta e non altrove nella scheda?
È stato utile?

Soluzione

Non preoccuparti di impostare la proprietà contextMenuStrip su TabControl. Piuttosto fallo in questo modo. Collegati all'evento MouseClick di tabControl, quindi mostra manualmente il menu di scelta rapida. Questo si attiva solo se si fa clic sulla scheda stessa in alto, non sulla pagina effettiva. Se si fa clic sulla pagina, quindi tabControl non riceve l'evento click, TabPage lo fa. Alcuni codici:

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


}

Altri suggerimenti

L'evento di apertura del menu di scelta rapida può essere utilizzato per risolvere entrambi i problemi

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 po 'in ritardo, ma ho trovato una soluzione per la prima parte della tua domanda. È possibile capire su quale scheda è stato fatto clic con il pulsante destro del mouse inviando un clic con il pulsante sinistro del mouse sull'applicazione. Questo seleziona la scheda, quindi ora puoi utilizzare la proprietà TabControl.SelectedTab per ottenere la scheda su cui l'utente ha fatto clic con il pulsante destro del mouse.

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

Stavo cercando una soluzione per lo stesso identico problema.
Dopo aver testato le risposte di @nisar e @BFree, sono arrivato a questo (avevo anche TabControl` all'interno di un pannello da qualche parte nel modulo):

  • Crea tabcontrol1
  • Iscriviti all'evento MouseClick
  • Crea 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;
            }
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top