C#中關於WinForm中重繪TabControl選項卡標題的問題
這裡說的是每個TabPage的頭部,也就是標題,不是工作區域。
最開始用到TabControl的時候,我的每個選項卡是寫死的,而後由於專案需求又動態添加了TabControl並生成各個選項卡,而兩次我都要重繪
其標題,因此在這裡把我當時兩種情形下重繪的方法通過一個例子一起分享出來。
首先先在窗體拖個Tabcontrol控制元件,然後更改了其Alignment屬性為Left,使其選項卡在左邊。然後可以通過更改其ItemSize調節每個選項卡的大
小。值得注意的是,因為在此是把TabControl向左旋轉了90°,所以此時設定寬的時候實際上改變的是它的高,設定高的時候實際上改變的是它的
寬。而且設定寬(改變高)發現無效是因為受選項卡文字字型所影響,可相應地改變字型尺寸。調整一番後的效果圖:
接著就要進入正題重繪其選項卡背景了。首先要把它的DrawMode屬性改為OwnerDrawFixed,改了這個才會讓使用者自己繪製標題生效。接著給
它新增DrawItem事件。事件重繪方法如下:
1 private void tabMain_DrawItem(object sender, DrawItemEventArgs e) 2 { 3 Bitmap b0 = new Bitmap(@"..\..\Images\1.jpg"); 4 Bitmap b1 = new Bitmap(@"..\..\Images\2.jpg"); 5 Bitmap b2 = new Bitmap(@"..\..\Images\3.jpg"); 6 Bitmap b3 = new Bitmap(@"..\..\Images\4.jpg"); 7 switch (e.Index) 8 { 9 case 0: 10 e.Graphics.DrawImage(b0, e.Bounds);11 break; 12 case 1: 13 e.Graphics.DrawImage(b1, e.Bounds); 14 break; 15 case 2: 16 e.Graphics.DrawImage(b2, e.Bounds); 17 break; 18 case 3: 19 e.Graphics.DrawImage(b3, e.Bounds); 20 break; 21 } 22 }
本文的圖片我都事先放在當前專案下的一個Images資料夾裡了。
最終效果圖:
以上是寫死的情況下為其重繪標題,現在來介紹當選項卡是動態生成時為其重繪標題的方法。在說明此之前,我們先為原有TabControl添
加SelectedIndexChanged事件,通過獲取其SelectedIndex從而知道哪個選項卡被點選了,在此,我在第二個選項卡里面動態新增另一個
TabControl並生成其各個TabPage。程式碼如下:
1 private void tabMain_SelectedIndexChanged(object sender, EventArgs e) 2 { 3 switch (tabMain.SelectedIndex) 4 { 5 case 0: 6 break; 7 case 1: 8 //假設動態生成的TabControl有4個選項卡 9 for (int i = 0; i < 4; i++) 10 { 11 TabPage page = new TabPage(); 12 page.Name = "page" + i.ToString(); 13 page.Text = (i + 1).ToString(); 14 this.tabSub.Controls.Add(page); 15 } 16 this.tabSub.ItemSize = new System.Drawing.Size(80, 80); 17 this.tabSub.Font = new System.Drawing.Font("宋體", 20); 18 this.tabSub.Dock = DockStyle.Fill; 19 this.tabMain.TabPages[1].Controls.Add(tabSub); 20 break; 21 case 2: 22 break; 23 case 3: 24 break; 25 } 26 }
在外部預先定義好要生成的TabControl變數:
TabControl tabSub = new TabControl();
效果如下:
好了,接下來也該為它重繪下標題了。首先在上面設定tabSub屬性的程式碼下新增這兩行:
this.tabSub.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.tabSub_DrawItem);
this.tabSub.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
第一行是為tabSub新增繪製標題的事件,第二行是為了讓系統使用我們自己繪製的樣式。
然後自己寫個繪製方法,程式碼如下:
1 private void tabSub_DrawItem(object sender, DrawItemEventArgs e) 2 { 3 List<string> imgPath = new List<string>() 4 { 5 @"..\..\Images\d.jpg", 6 @"..\..\Images\s.jpg", 7 @"..\..\Images\n.jpg", 8 @"..\..\Images\x.jpg" 9 }; 10 for (int i = 0; i < this.tabSub.TabCount; i++) 11 { 12 Bitmap b = new Bitmap(imgPath[i]); 13 if (e.Index == i) 14 { 15 e.Graphics.DrawImage(b, e.Bounds); 16 } 17 } 18 }
效果如下:
OK,至此大功告成。當然上述程式碼是有缺陷的,當你輪換左邊選項卡最後又點到第二個選項卡時,它會再載入多一次,這個只需要在當初繪製的時
候加個判斷就行了,可以判斷當前選項卡下是否已經包含了這些控制元件,或者定義個布林變數用來判斷是否已經載入就可以了。