2010-07-06 17 views
24

c'è qualcuno può dirmi come aggiungere il pulsante di chiusura in ogni scheda utilizzando tabControl in C#? Ho intenzione di utilizzare il pulsante pic per la sostituzione [x] nella mia scheda ..Pulsante Chiudi in tabControl

grazie

+0

[TabControl con Chiudi e Aggiungi Button] (http://stackoverflow.com/a/36900582/3110834) –

+0

[pulsante Chiudi per TabPages di TabControl da destra a sinistra] (http://stackoverflow.com/a/34509304/3110834) –

risposta

46

Senza derivare una classe, ecco un frammento di pulito: http://www.dotnetthoughts.net/implementing-close-button-in-tab-pages/

Impostare la proprietà del DrawMode Tab Control to OwnerDrawFixed. Questa proprietà decide se il sistema o lo sviluppatore dipingono le didascalie. Aggiungere il codice nell'evento DrawItem del controllo Struttura a schede: questo evento verrà richiamato per la colorazione di ogni pagina scheda.

//This code will render a "x" mark at the end of the Tab caption. 
e.Graphics.DrawString("x", e.Font, Brushes.Black, e.Bounds.Right - 15, e.Bounds.Top + 4); 
e.Graphics.DrawString(this.tabControl1.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + 12, e.Bounds.Top + 4); 
e.DrawFocusRectangle(); 

Ora per vicino l'azione pulsante, abbiamo bisogno di aggiungere il seguente codice all'evento MouseDown del Controllo Tab.

//Looping through the controls. 
for (int i = 0; i < this.tabControl1.TabPages.Count; i++) 
{ 
    Rectangle r = tabControl1.GetTabRect(i); 
    //Getting the position of the "x" mark. 
    Rectangle closeButton = new Rectangle(r.Right - 15, r.Top + 4, 9, 7); 
    if (closeButton.Contains(e.Location)) 
    { 
     if (MessageBox.Show("Would you like to Close this Tab?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
     { 
      this.tabControl1.TabPages.RemoveAt(i); 
      break; 
     } 
    } 
} 
+3

Questo merita più voti. Mi ha davvero aiutato. Nota a margine: usare 'tabControlBottom.SizeMode = TabSizeMode.Fixed;' e 'tabControlBottom.ItemSize' per impostare la larghezza e l'altezza della linguetta. –

+0

Non sono sicuro che il codice sia bacato o sto sbagliando. Sto usando il codice esattamente come questo (taglia e incolla, anche!), Le singole schede non prendono in considerazione l'ulteriore spazio per il pulsante "x" e in quanto tale, la scheda è in realtà solo abbastanza grande da contenere il testo (l'ultima lettera del testo e la 'x' si sovrappongono) – Beta033

+2

Aggiungere alcuni spazi vuoti alla fine di ogni stringa che si passa come nome per la scheda. Questo riserva sempre molto spazio per la 'x'. – Karlovsky120

5

aggiunta alle altre risposte ... perché iterazione attraverso tutte le schede sul mouse evento click quando possiamo solo rilevare la scheda corrente con .SelectedIndex e .SelectedTab?

Come così:

private void tabControl1_MouseDown(object sender, MouseEventArgs e) 
{ 
    Rectangle r = tabControl1.GetTabRect(this.tabControl1.SelectedIndex); 
    Rectangle closeButton = new Rectangle(r.Right - 15, r.Top + 4, 9, 7); 
    if (closeButton.Contains(e.Location)) 
    { 
     this.tabControl1.TabPages.Remove(this.tabControl1.SelectedTab); 
    } 
} 

quello che sembra accadere è il momento in cui si fa clic su un TabPage per chiuderla, sia anche selezionato, permettendo così il pulsante di chiusura per chiudere il TabPage destra. Per me funziona, ma ti prego di prenderlo con molta attenzione, perché non sono completamente sicuro dei possibili inconvenienti (la mia frase iniziale non era una domanda completamente retorica dato che sono piuttosto nuova a .Net ...).

+0

Un piccolo problema con questo codice è che quando si aprono molte schede e le si hanno su più righe di schede , se provi a chiudere una scheda su una riga diversa dalla riga di schede attualmente attiva, questo codice renderà attiva solo la riga di schede che contiene la scheda che vogliamo chiudere e selezionarla, ma non chiuderla. Sto solo segnalando questo, non ho il tempo di ispezionarlo ulteriormente ora, ma ritengo che la soluzione non debba essere così difficile. –

+0

Non ho ancora provato questo, ma vedo quello che potrebbe essere un problema. Se sono aperte più schede, (schede A, B e C). Se lavori nella scheda C e decidi di chiudere la scheda A senza selezionarla (aprirla).Facendo clic sulla X di chiusura nella scheda A non chiudere la scheda C mentre chiude la scheda selezionata? – DDuffy

+0

@DDuffy no, non chiuderebbe la scheda sbagliata nella mia app. Nel mio caso, nel momento in cui fai clic sulla X, selezioni anche la scheda, quindi quella corretta verrà chiusa. –

0

Prova di questo codice:

private Point _imageLocation = new Point(13, 5); 
     private Point _imgHitArea = new Point(13, 2); 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed; 
    tabControl1.DrawItem += tabControl1_DrawItem; 
    CloseImage = WindowsFormsApplication3.Properties.Resources.closeR; 
    tabControl1.Padding = new Point(10, 3); 
     } 


    private void TabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) 
     { 
      try 
      { 
       Image img = new Bitmap(CloseImage); 
       Rectangle r = e.Bounds; 
       r = this.tabControl1.GetTabRect(e.Index); 
       r.Offset(2, 2); 
       Brush TitleBrush = new SolidBrush(Color.Black); 
       Font f = this.Font; 
       string title = this.tabControl1.TabPages[e.Index].Text; 

       e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y)); 

       if (tabControl1.SelectedIndex >= 1) 
       { 
        e.Graphics.DrawImage(img, new Point(r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y)); 
       } 
      } 
      catch (Exception) { } 
     } 


private void TabControl1_Mouse_Click(object sender, System.Windows.Forms.DrawItemEventArgs e) 
{ 

TabControl tc = (TabControl)sender; 
Point p = e.Location; 
int _tabWidth = 0; 
_tabWidth = this.tabControl1.GetTabRect(tc.SelectedIndex).Width - (_imgHitArea.X); 
Rectangle r = this.tabControl1.GetTabRect(tc.SelectedIndex); 
r.Offset(_tabWidth, _imgHitArea.Y); 
r.Width = 16; 
r.Height = 16; 
if (tabControl1.SelectedIndex >= 1) 
{ 
    if (r.Contains(p)) 
    { 
     TabPage TabP = (TabPage)tc.TabPages[tc.SelectedIndex]; 
     tc.TabPages.Remove(TabP); 
    } 

} 
} 

Guarda this frammento di codice

Problemi correlati