2010-07-06 74 views
24

有沒有人可以告訴我如何在C#中使用tabControl的每個選項卡中添加關閉按鈕? 我打算使用按鈕PIC在我的標籤替換[X] ..tabControl中的關閉按鈕

謝謝

+0

[TabControl的與關閉,並添加按鈕(http://stackoverflow.com/a/36900582/3110834) – 2017-02-13 18:54:05

+0

[關閉按鈕爲TabPages從右到左TabControl](http://stackoverflow.com/a/34509304/3110834) – 2017-02-13 18:55:14

回答

46

沒有派生一個類,這裏​​是一個整潔的片段: http://www.dotnetthoughts.net/implementing-close-button-in-tab-pages/

設置的DrawMode屬性選項卡控制爲OwnerDrawFixed。此屬性決定系統還是開發人員繪製字幕。 將代碼添加到選項卡控件的DrawItem事件中 - 將調用此事件來繪製每個選項卡頁面。

//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(); 

現在要關閉按鈕操作,我們需要將下面的代碼添加到Tab控件的MouseDown事件中。

//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

這值得更多的選票。它真的幫助了我。注意:使用'tabControlBottom.SizeMode = TabSizeMode.Fixed;'和'tabControlBottom.ItemSize'來設置標籤的寬度和高度。 – 2013-04-18 11:28:09

+0

不知道如果代碼是越野車,或者我只是做錯了。我使用完全像這樣的代碼(剪切和粘貼,甚至!),各個選項卡不考慮「x」按鈕的額外空間,因此該選項卡實際上僅足以容納文本(文本的最後一個字母和'x'彼此重疊) – Beta033 2016-01-13 18:13:31

+2

在作爲選項卡名稱傳遞的每個字符串的末尾添加幾個空格。這將永遠爲'x'保留這麼多空間。 – Karlovsky120 2016-01-15 23:03:23

5

添加到其他的答案......爲什麼迭代通過鼠標點擊事件的所有標籤時,我們可以只檢測與.SelectedIndex和.SelectedTab當前選項卡?

像這樣:

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

什麼似乎是,你在一個標籤頁點擊關閉它的那一刻,它也被選中的情況發生,從而使關閉按鈕來關閉右標籤頁。 對我來說,它的工作原理,但請特別注意這一點,因爲我不完全確定可能的缺點(我的初始語句並不是一個完全修辭的問題,因爲我對.NET有點新鮮......)。

+0

這個代碼的一個小問題是,當你有很多標籤打開,你有他們在多行選項卡,如果您嘗試關閉與當前活動的選項卡不同的行上的選項卡,那麼此代碼將只激活包含要關閉的選項卡的選項卡行,並選擇該選項卡,但不會關閉它。我只是在報道這一點,現在沒有時間進一步檢查它,但我覺得解決方案不能這麼難。 – 2016-03-22 14:14:05

+0

還沒有測試過,但我看到什麼可能是一個問題。如果您打開了多個選項卡,(選項卡A,B和C)。如果您在標籤C中工作並決定要關閉標籤A而不選擇(打開)它。單擊標籤A中的結尾X會不會關閉標籤C,因爲它正在關閉所選標籤? – DDuffy 2016-12-28 09:17:21

+0

@DDuffy不,它不會關閉我的應用程序中的錯誤標籤。在我的情況下,當你點擊X時,你也選擇標籤,所以正確的一個將被關閉。 – 2016-12-29 10:10:56

0

試試這個代碼:

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

} 
} 

this代碼片段