web-dev-qa-db-fra.com

Personnalisation d'un TabControl pour la fermeture d'onglets individuels

Mon scénario est le suivant:

Je travaille sur une application Winforms en C # qui comporte un bouton à l'intérieur de la page principale d'un onglet de contrôle qui générera un autre onglet à chaque clic. Chaque nouvelle page contient une mise en page définie par un contrôle utilisateur. 

Mes questions sont:

  1. Comment puis-je permettre à l'utilisateur de fermer l'un des onglets créés dynamiquement au moment de l'exécution?

  2. Comment puis-je modifier le tabcontrol lui-même afin qu'il ait un petit «X» dans chaque onglet sur lequel l'utilisateur peut cliquer pour fermer cet onglet? (Comme Firefox a)

  3. Comment puis-je exposer la propriété SelectedIndex de tabcontrol au contrôle utilisateur si je veux fermer l'onglet avec un bouton à l'intérieur du contrôle utilisateur?

18
THE DOCTOR

J'ai créé un contrôle d'onglet dérivé il y a environ un an. Je ne vais pas poster la source ici, car elle compte environ 700 lignes et est codée de manière assez compliquée. Je trouverai peut-être un peu de temps pour nettoyer le code et le publier ici. Pour l'instant, je vais décrire brièvement la façon dont il est construit.

Chaque page à onglet a une icône «X» sur le left du titre et les pages à onglet prennent en charge le réordonnancement par glisser-déposer et en les déplaçant entre plusieurs contrôles de tabulation.

Je choisis le moyen le plus simple d’obtenir l’icône dans les pages à onglet. Le contrôle onglet a la propriété TabControl.ImageList et une page à onglet a une propriété TabPage.ImageIndex . Je viens donc d'ajouter trois icônes à une liste d'images - normales, survolées, enfoncées - et de traiter les événements de la souris.

Avec TabControl.GetTabRect() vous pouvez tester si la souris survole une page à onglet spécifique et, avec quelques calculs, vous constaterez qu’elle se trouve au-dessus de l’icône. Ensuite, il vous suffit de changer l'icône en fonction de l'état du bouton de la souris et éventuellement de supprimer la page d'onglets sous la souris si le bouton a été enfoncé.

Le principal problème de cette solution est que, pour calculer si la souris est au-dessus de l'icône, il faut savoir où l'icône est peinte par rapport à la page à onglet et cela pourrait changer avec une nouvelle version de Windows. Et l’icône est à gauche du titre, mais cela n’a pas l’air mauvais.

9
Daniel Brückner

J'ai trouvé ce code et m'a été très utile:

private void tabControl_MouseUp(object sender, MouseEventArgs e)
{
    // check if the right mouse button was pressed
    if(e.Button == MouseButtons.Right)
    {
        // iterate through all the tab pages
        for(int i = 0; i < tabControl1.TabCount; i++)
        {
            // get their rectangle area and check if it contains the mouse cursor
            Rectangle r = tabControl1.GetTabRect(i);
            if (r.Contains(e.Location))
            {
                // show the context menu here
                System.Diagnostics.Debug.WriteLine("TabPressed: " + i);
             }
        }
    }
}

TabControl: comment capturer la souris par clic droit sur un onglet

14
Vallel

J'ai fait ce qui suit: À l'étape create (ajouter) TabPage, j'ai ajouté une toolStrip

ToolStrip ts = new ToolStrip();
ts.Dock = DockStyle.Top;
ts.RightToLeft = System.Windows.Forms.RightToLeft.Yes;

Ensuite, créez le bouton X et ajoutez-le à toolstrip

ToolStripButton ToolStripButton = new ToolStripButton("X");
ts.Items.Add(ToolStripButton);

créer un événement en cliquant sur le bouton X 

ToolStripButton.Click += new EventHandler(ToolStripButton_Click);

ajouter toolstrip à la tabpage

tabControl1.TabPages[curenttabpage].Controls.Add(ts);

now pour le ToolStripButton_Click est la suivante:

void ToolStripButton_Click(object sender, EventArgs e)
{ 
 ToolStripButton t = (ToolStripButton)(sender);
 ToolStrip ts = t.Owner;
 TabPage tb = (TabPage)
 (ts.Parent);tabControl1.TabPages.Remove(tb);
}

Peut-être que ce n’est pas comme vous voulez, mais cela fonctionnera bien.

6
Muhammad Hamad

J'ai créé une configuration similaire.

Chaque contrôle ajouté à la page à onglet au moment de l'exécution est dérivé d'un contrôle de base spécial que j'ai créé. Ce contrôle de base possède un bouton de fermeture (ainsi que d’autres fonctionnalités telles que le drapeau permettant de fermer en toute sécurité).

Fermer le code de tabulation que j'utilise sur mon contrôle de base:

 TabPage tabpage = (TabPage)this.Parent;
TabControl tabControl = (TabControl)tabpage.Parent;

tabControl.TabPages.Remove(parent);
2
Crispy

Je sais que c’est un vieux sujet, mais j’ai trouvé ce link qui vous permettra de "masquer" les onglets dans un tableau et vous pourrez ensuite recharger les onglets que vous voulez au moment de l’exécution. J'ai ajouté ceci plus pour un endroit que je peux facilement le retrouver.

1
Mark Kram

Ce code peut aider à fermer les contrôles de tabulation avec le clic du milieu de la souris: 

            private void tabControl1_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button != System.Windows.Forms.MouseButtons.Middle)
                    return;

                for (int i = 0; i < MainTabControl.TabPages.Count; i++)
                {
                    if (this.MainTabControl.GetTabRect(i).Contains(e.Location))
                    {
                        this.MainTabControl.TabPages.RemoveAt(i);
                        return;
                    }
                }
            }
0