WinForm中重繪TabControl選項卡標題


最近開發WinForm頻繁使用了TabControl控件,這個控件的選項卡沒有BackgroundImage這個屬性,那么如何為其各個選項卡添加背景圖片呢?(這里說的是每個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         }
View Code

 本文的圖片我都事先放在當前項目下的一個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         }
View Code

在外部預先定義好要生成的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         }
View Code

效果如下:

OK,至此大功告成。當然上述代碼是有缺陷的,當你輪換左邊選項卡最后又點到第二個選項卡時,它會再加載多一次,這個只需要在當初繪制的時候加個判斷就行了,可以判斷當前選項卡下是否已經包含了這些控件,或者定義個布爾變量用來判斷是否已經加載就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM