1. 程式人生 > >(三十五)c#Winform自定義控制元件-Tab頁

(三十五)c#Winform自定義控制元件-Tab頁

前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制元件,於是就有了本系列文章。

開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control

如果覺得寫的還行,請點個 star 支援一下吧

歡迎前來交流探討: 企鵝群568015492 

目錄

https://www.cnblogs.com/bfyx/p/11364884.html

準備工作

此控制元件在https://www.cnblogs.com/belx/articles/9188577.html基礎上調整修改,特此感謝

開始

新增一個使用者元件,命名TabControlExt,繼承自TabControl

幾個重寫屬性

 1  private Color _backColor = Color.White;
 2         [Browsable(true)]
 3         [EditorBrowsable(EditorBrowsableState.Always)]
 4         [DefaultValue(typeof(Color), "White")]
 5         public override Color BackColor
 6         {
 7             get { return _backColor; }
 8             set
 9             {
10                 _backColor = value;
11                 base.Invalidate(true);
12             }
13         }
14 
15         private Color _borderColor = Color.FromArgb(232, 232, 232);
16         [DefaultValue(typeof(Color), "232, 232, 232")]
17         [Description("TabContorl邊框色")]
18         public Color BorderColor
19         {
20             get { return _borderColor; }
21             set
22             {
23                 _borderColor = value;
24                 base.Invalidate(true);
25             }
26         }
27 
28         private Color _headSelectedBackColor = Color.FromArgb(255, 85, 51);
29         [DefaultValue(typeof(Color), "255, 85, 51")]
30         [Description("TabPage頭部選中後的背景顏色")]
31         public Color HeadSelectedBackColor
32         {
33             get { return _headSelectedBackColor; }
34             set { _headSelectedBackColor = value; }
35         }
36 
37         private Color _headSelectedBorderColor = Color.FromArgb(232, 232, 232);
38         [DefaultValue(typeof(Color), "232, 232, 232")]
39         [Description("TabPage頭部選中後的邊框顏色")]
40         public Color HeadSelectedBorderColor
41         {
42             get { return _headSelectedBorderColor; }
43             set { _headSelectedBorderColor = value; }
44         }
45 
46         private Color _headerBackColor = Color.White;
47         [DefaultValue(typeof(Color), "White")]
48         [Description("TabPage頭部預設背景顏色")]
49         public Color HeaderBackColor
50         {
51             get { return _headerBackColor; }
52             set { _headerBackColor = value; }
53         }

重寫背景

 1 protected override void OnPaintBackground(PaintEventArgs pevent)
 2         {
 3             if (this.DesignMode == true)
 4             {
 5                 LinearGradientBrush backBrush = new LinearGradientBrush(
 6                             this.Bounds,
 7                             SystemColors.ControlLightLight,
 8                             SystemColors.ControlLight,
 9                             LinearGradientMode.Vertical);
10                 pevent.Graphics.FillRectangle(backBrush, this.Bounds);
11                 backBrush.Dispose();
12             }
13             else
14             {
15                 this.PaintTransparentBackground(pevent.Graphics, this.ClientRectangle);
16             }
17         }
18  /// <summary>
19         ///  TabContorl 背景色設定
20         /// </summary>
21         /// <param name="g"></param>
22         /// <param name="clipRect"></param>
23         protected void PaintTransparentBackground(Graphics g, Rectangle clipRect)
24         {
25             if ((this.Parent != null))
26             {
27                 clipRect.Offset(this.Location);
28                 PaintEventArgs e = new PaintEventArgs(g, clipRect);
29                 GraphicsState state = g.Save();
30                 g.SmoothingMode = SmoothingMode.HighSpeed;
31                 try
32                 {
33                     g.TranslateTransform((float)-this.Location.X, (float)-this.Location.Y);
34                     this.InvokePaintBackground(this.Parent, e);
35                     this.InvokePaint(this.Parent, e);
36                 }
37                 finally
38                 {
39                     g.Restore(state);
40                     clipRect.Offset(-this.Location.X, -this.Location.Y);
41                     //新加片段,待測試
42                     using (SolidBrush brush = new SolidBrush(_backColor))
43                     {
44                         clipRect.Inflate(1, 1);
45                         g.FillRectangle(brush, clipRect);
46                     }
47                 }
48             }
49             else
50             {
51                 System.Drawing.Drawing2D.LinearGradientBrush backBrush = new System.Drawing.Drawing2D.LinearGradientBrush(this.Bounds, SystemColors.ControlLightLight, SystemColors.ControlLight, System.Drawing.Drawing2D.LinearGradientMode.Vertical);
52                 g.FillRectangle(backBrush, this.Bounds);
53                 backBrush.Dispose();
54             }
55         }

重繪

1  protected override void OnPaint(PaintEventArgs e)
2         {
3             // Paint the Background 
4             base.OnPaint(e);
5             this.PaintTransparentBackground(e.Graphics, this.ClientRectangle);
6             this.PaintAllTheTabs(e);
7             this.PaintTheTabPageBorder(e);
8             this.PaintTheSelectedTab(e);
9         }

輔助函式

  1 private void PaintAllTheTabs(System.Windows.Forms.PaintEventArgs e)
  2         {
  3             if (this.TabCount > 0)
  4             {
  5                 for (int index = 0; index < this.TabCount; index++)
  6                 {
  7                     this.PaintTab(e, index);
  8                 }
  9             }
 10         }
 11 
 12         private void PaintTab(System.Windows.Forms.PaintEventArgs e, int index)
 13         {
 14             GraphicsPath path = this.GetTabPath(index);
 15             this.PaintTabBackground(e.Graphics, index, path);
 16             this.PaintTabBorder(e.Graphics, index, path);
 17             this.PaintTabText(e.Graphics, index);
 18             this.PaintTabImage(e.Graphics, index);
 19         }
 20 
 21         /// <summary>
 22         /// 設定選項卡頭部顏色
 23         /// </summary>
 24         /// <param name="graph"></param>
 25         /// <param name="index"></param>
 26         /// <param name="path"></param>
 27         private void PaintTabBackground(System.Drawing.Graphics graph, int index, System.Drawing.Drawing2D.GraphicsPath path)
 28         {
 29             Rectangle rect = this.GetTabRect(index);
 30             System.Drawing.Brush buttonBrush = new System.Drawing.Drawing2D.LinearGradientBrush(rect, _headerBackColor, _headerBackColor, LinearGradientMode.Vertical);  //非選中時候的 TabPage 頁頭部背景色
 31             graph.FillPath(buttonBrush, path);
 32             //if (index == this.SelectedIndex)
 33             //{
 34             //    //buttonBrush = new System.Drawing.SolidBrush(_headSelectedBackColor);
 35             //    graph.DrawLine(new Pen(_headerBackColor), rect.Right+2, rect.Bottom, rect.Left + 1, rect.Bottom);
 36             //}
 37             buttonBrush.Dispose();
 38         }
 39 
 40         /// <summary>
 41         /// 設定選項卡頭部邊框色
 42         /// </summary>
 43         /// <param name="graph"></param>
 44         /// <param name="index"></param>
 45         /// <param name="path"></param>
 46         private void PaintTabBorder(System.Drawing.Graphics graph, int index, System.Drawing.Drawing2D.GraphicsPath path)
 47         {
 48             Pen borderPen = new Pen(_borderColor);// TabPage 非選中時候的 TabPage 頭部邊框色
 49             if (index == this.SelectedIndex)
 50             {
 51                 borderPen = new Pen(_headSelectedBorderColor); // TabPage 選中後的 TabPage 頭部邊框色
 52             }
 53             graph.DrawPath(borderPen, path);
 54             borderPen.Dispose();
 55         }
 56 
 57         private void PaintTabImage(System.Drawing.Graphics g, int index)
 58         {
 59             Image tabImage = null;
 60             if (this.TabPages[index].ImageIndex > -1 && this.ImageList != null)
 61             {
 62                 tabImage = this.ImageList.Images[this.TabPages[index].ImageIndex];
 63             }
 64             else if (this.TabPages[index].ImageKey.Trim().Length > 0 && this.ImageList != null)
 65             {
 66                 tabImage = this.ImageList.Images[this.TabPages[index].ImageKey];
 67             }
 68             if (tabImage != null)
 69             {
 70                 Rectangle rect = this.GetTabRect(index);
 71                 g.DrawImage(tabImage, rect.Right - rect.Height - 4, 4, rect.Height - 2, rect.Height - 2);
 72             }
 73         }
 74 
 75         private void PaintTabText(System.Drawing.Graphics graph, int index)
 76         {
 77             string tabtext = this.TabPages[index].Text;
 78 
 79             System.Drawing.StringFormat format = new System.Drawing.StringFormat();
 80             format.Alignment = StringAlignment.Near;
 81             format.LineAlignment = StringAlignment.Center;
 82             format.Trimming = StringTrimming.EllipsisCharacter;
 83 
 84             Brush forebrush = null;
 85 
 86             if (this.TabPages[index].Enabled == false)
 87             {
 88                 forebrush = SystemBrushes.ControlDark;
 89             }
 90             else
 91             {
 92                 forebrush = SystemBrushes.ControlText;
 93             }
 94 
 95             Font tabFont = this.Font;
 96             if (index == this.SelectedIndex)
 97             {
 98                 if (this.TabPages[index].Enabled != false)
 99                 {
100                     forebrush = new SolidBrush(_headSelectedBackColor);
101                 }
102             }
103 
104             Rectangle rect = this.GetTabRect(index);
105 
106             var txtSize = ControlHelper.GetStringWidth(tabtext, graph, tabFont);
107             Rectangle rect2 = new Rectangle(rect.Left + (rect.Width - txtSize) / 2 - 1, rect.Top, rect.Width, rect.Height);
108 
109             graph.DrawString(tabtext, tabFont, forebrush, rect2, format);
110         }
111 
112         /// <summary>
113         /// 設定 TabPage 內容頁邊框色
114         /// </summary>
115         /// <param name="e"></param>
116         private void PaintTheTabPageBorder(System.Windows.Forms.PaintEventArgs e)
117         {
118             if (this.TabCount > 0)
119             {
120                 Rectangle borderRect = this.TabPages[0].Bounds;
121                 //borderRect.Inflate(1, 1);
122                 Rectangle rect = new Rectangle(borderRect.X - 2, borderRect.Y-1, borderRect.Width + 5, borderRect.Height+2);
123                 ControlPaint.DrawBorder(e.Graphics, rect, this.BorderColor, ButtonBorderStyle.Solid);
124             }
125         }
126 
127         /// <summary>
128         /// // TabPage 頁頭部間隔色
129         /// </summary>
130         /// <param name="e"></param>
131         private void PaintTheSelectedTab(System.Windows.Forms.PaintEventArgs e)
132         {
133             if (this.SelectedIndex == -1)
134                 return;
135             Rectangle selrect;
136             int selrectRight = 0;
137             selrect = this.GetTabRect(this.SelectedIndex);
138             selrectRight = selrect.Right;
139             e.Graphics.DrawLine(new Pen(_headSelectedBackColor), selrect.Left, selrect.Bottom + 1, selrectRight, selrect.Bottom + 1);
140         }
141 
142         private GraphicsPath GetTabPath(int index)
143         {
144             System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
145             path.Reset();
146 
147             Rectangle rect = this.GetTabRect(index);
148 
149             switch (Alignment)
150             {
151                 case TabAlignment.Top:
152 
153                     break;
154                 case TabAlignment.Bottom:
155 
156                     break;
157                 case TabAlignment.Left:
158 
159                     break;
160                 case TabAlignment.Right:
161 
162                     break;
163             }
164 
165             path.AddLine(rect.Left, rect.Top, rect.Left, rect.Bottom + 1);
166             path.AddLine(rect.Left, rect.Top, rect.Right , rect.Top);
167             path.AddLine(rect.Right , rect.Top, rect.Right , rect.Bottom + 1);
168             path.AddLine(rect.Right , rect.Bottom + 1, rect.Left, rect.Bottom + 1);
169 
170             return path;
171         }

2個重寫函式處理字型相關

 1  [DllImport("user32.dll")]
 2         private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
 3 
 4         private const int WM_SETFONT = 0x30;
 5         private const int WM_FONTCHANGE = 0x1d;
 6 
 7         protected override void OnCreateControl()
 8         {
 9             base.OnCreateControl();
10             this.OnFontChanged(EventArgs.Empty);
11         }
12 
13         protected override void OnFontChanged(EventArgs e)
14         {
15             base.OnFontChanged(e);
16             IntPtr hFont = this.Font.ToHfont();
17             SendMessage(this.Handle, WM_SETFONT, hFont, (IntPtr)(-1));
18             SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
19             this.UpdateStyles();
20         }

 

用處及效果

最後的話

如果你喜歡的話,請到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點個星