Vs自带的TabControl太丑,想改造一下。
自定义TabControl,从TabControl派生一个自定义的标签控件GTabControl。
public class GTabControl :TabControl
在构造函数中添加如下代码:
1 base.SetStyle(2 ControlStyles.UserPaint | // 控件将自行绘制,而不是通过操作系统来绘制3 ControlStyles.OptimizedDoubleBuffer | // 该控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁4 ControlStyles.AllPaintingInWmPaint | // 控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁5 ControlStyles.ResizeRedraw | // 在调整控件大小时重绘控件6 ControlStyles.SupportsTransparentBackColor, // 控件接受 alpha 组件小于 255 的 BackColor 以模拟透明7 true); // 设置以上值为 true8 base.UpdateStyles();
这段代码的意思就像注释里说的,注意ControlStyles这个枚举是可以按位组合的,所以上面要用「或(|)」来进行连接,这样系统就会完全忽视TabControl这个基类的界面显示,而使用我们自己的方式来呈现UI。()
以上是学习的过程。
1 using System.Drawing; 2 using System.Windows.Forms; 3 using System.Drawing.Drawing2D; 4 using System; 5 using System.Runtime.InteropServices; 6 7 namespace CSharpCustomTabControl 8 { 9 ///10 /// Description of CustomTabControl. 11 /// 12 [ToolboxBitmap(typeof(TabControl))] 13 public class CustomTabControl : TabControl 14 { 15 16 public CustomTabControl() : base() 17 { 18 if (this._DisplayManager.Equals(TabControlDisplayManager.Custom)) { 19 this.SetStyle(ControlStyles.UserPaint, true); 20 this.ItemSize = new Size(0, 15); 21 this.Padding = new Point(9,0); 22 } 23 24 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 25 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 26 this.SetStyle(ControlStyles.ResizeRedraw, true); 27 this.ResizeRedraw = true; 28 } 29 30 TabControlDisplayManager _DisplayManager = TabControlDisplayManager.Custom; 31 32 [System.ComponentModel.DefaultValue(typeof(TabControlDisplayManager), "Custom")] 33 public TabControlDisplayManager DisplayManager { 34 get { 35 return this._DisplayManager; 36 } 37 set { 38 if (this._DisplayManager != value) { 39 if (this._DisplayManager.Equals(TabControlDisplayManager.Custom)) { 40 this.SetStyle(ControlStyles.UserPaint, true); 41 this.ItemSize = new Size(0, 15); 42 this.Padding = new Point(9,0); 43 } else { 44 this.ItemSize = new Size(0, 0); 45 this.Padding = new Point(6,3); 46 this.SetStyle(ControlStyles.UserPaint, false); 47 } 48 } 49 } 50 } 51 52 protected override void OnPaintBackground(PaintEventArgs pevent) 53 { 54 if (this.DesignMode == true) { 55 LinearGradientBrush backBrush = new LinearGradientBrush( 56 this.Bounds, 57 SystemColors.ControlLightLight, 58 SystemColors.ControlLight, 59 LinearGradientMode.Vertical); 60 pevent.Graphics.FillRectangle(backBrush, this.Bounds); 61 backBrush.Dispose(); 62 } else { 63 this.PaintTransparentBackground(pevent.Graphics, this.ClientRectangle); 64 } 65 } 66 67 protected void PaintTransparentBackground(Graphics g, Rectangle clipRect) 68 { 69 if ((this.Parent != null)) { 70 clipRect.Offset(this.Location); 71 PaintEventArgs e = new PaintEventArgs(g, clipRect); 72 GraphicsState state = g.Save(); 73 g.SmoothingMode = SmoothingMode.HighSpeed; 74 try { 75 g.TranslateTransform((float)-this.Location.X, (float)-this.Location.Y); 76 this.InvokePaintBackground(this.Parent, e); 77 this.InvokePaint(this.Parent, e); 78 } 79 80 finally { 81 g.Restore(state); 82 clipRect.Offset(-this.Location.X, -this.Location.Y); 83 } 84 } 85 else { 86 System.Drawing.Drawing2D.LinearGradientBrush backBrush = new System.Drawing.Drawing2D.LinearGradientBrush(this.Bounds, SystemColors.ControlLightLight, SystemColors.ControlLight, System.Drawing.Drawing2D.LinearGradientMode.Vertical); 87 g.FillRectangle(backBrush, this.Bounds); 88 backBrush.Dispose(); 89 } 90 } 91 92 protected override void OnPaint(PaintEventArgs e) 93 { 94 95 // Paint the Background 96 this.PaintTransparentBackground(e.Graphics, this.ClientRectangle); 97 98 this.PaintAllTheTabs(e); 99 this.PaintTheTabPageBorder(e);100 this.PaintTheSelectedTab(e);101 }102 103 private void PaintAllTheTabs(System.Windows.Forms.PaintEventArgs e) {104 if (this.TabCount > 0) {105 for (int index = 0; index < this.TabCount ; index++){106 this.PaintTab(e, index);107 }108 }109 }110 111 private void PaintTab(System.Windows.Forms.PaintEventArgs e, int index) {112 GraphicsPath path = this.GetPath(index);113 this.PaintTabBackground(e.Graphics, index, path);114 this.PaintTabBorder(e.Graphics, index, path);115 this.PaintTabText(e.Graphics, index);116 this.PaintTabImage(e.Graphics, index);117 }118 119 private void PaintTabBackground(System.Drawing.Graphics graph, int index, System.Drawing.Drawing2D.GraphicsPath path){120 Rectangle rect = this.GetTabRect(index);121 System.Drawing.Brush buttonBrush =122 new System.Drawing.Drawing2D.LinearGradientBrush(123 rect,124 SystemColors.ControlLightLight,125 SystemColors.ControlLight,126 LinearGradientMode.Vertical);127 128 if (index == this.SelectedIndex) {129 buttonBrush = new System.Drawing.SolidBrush(SystemColors.ControlLightLight);130 }131 132 graph.FillPath(buttonBrush, path);133 buttonBrush.Dispose();134 }135 136 private void PaintTabBorder(System.Drawing.Graphics graph, int index, System.Drawing.Drawing2D.GraphicsPath path){137 Pen borderPen = new Pen(SystemColors.ControlDark);138 139 if (index == this.SelectedIndex) {140 borderPen = new Pen(ThemedColors.ToolBorder);141 }142 graph.DrawPath(borderPen, path);143 borderPen.Dispose();144 }145 146 private void PaintTabImage(System.Drawing.Graphics graph, int index){147 Image tabImage = null;148 if (this.TabPages[index].ImageIndex > -1 && this.ImageList != null) {149 tabImage = this.ImageList.Images[this.TabPages[index].ImageIndex];150 }else if (this.TabPages[index].ImageKey.Trim().Length > 0 && this.ImageList != null){151 tabImage = this.ImageList.Images[this.TabPages[index].ImageKey]; 152 }153 if ( tabImage != null) {154 Rectangle rect = this.GetTabRect(index);155 graph.DrawImage(tabImage, rect.Right - rect.Height - 4, 4, rect.Height - 2, rect.Height - 2);156 }157 }158 159 private void PaintTabText(System.Drawing.Graphics graph, int index)160 {161 Rectangle rect = this.GetTabRect(index);162 Rectangle rect2 = new Rectangle(rect.Left + 8, rect.Top + 1, rect.Width - 6, rect.Height);163 if (index == 0) rect2 = new Rectangle(rect.Left + rect.Height, rect.Top + 1, rect.Width - rect.Height, rect.Height); 164 165 string tabtext = this.TabPages[index].Text;166 167 System.Drawing.StringFormat format = new System.Drawing.StringFormat();168 format.Alignment = StringAlignment.Near;169 format.LineAlignment = StringAlignment.Center;170 format.Trimming = StringTrimming.EllipsisCharacter;171 172 Brush forebrush = null;173 174 if (this.TabPages[index].Enabled == false) {175 forebrush = SystemBrushes.ControlDark;176 }177 else {178 forebrush = SystemBrushes.ControlText;179 }180 181 Font tabFont = this.Font;182 if (index == this.SelectedIndex) {183 tabFont = new Font(this.Font, FontStyle.Bold);184 if (index == 0) {185 rect2 = new Rectangle(rect.Left + rect.Height, rect.Top + 1, rect.Width - rect.Height + 5, rect.Height);186 }187 }188 189 graph.DrawString(tabtext, tabFont, forebrush, rect2, format);190 191 }192 193 private void PaintTheTabPageBorder(System.Windows.Forms.PaintEventArgs e) {194 if (this.TabCount > 0) {195 Rectangle borderRect= this.TabPages[0].Bounds;196 borderRect.Inflate(1, 1);197 ControlPaint.DrawBorder(e.Graphics, borderRect, ThemedColors.ToolBorder, ButtonBorderStyle.Solid);198 }199 }200 201 private void PaintTheSelectedTab(System.Windows.Forms.PaintEventArgs e) {202 Rectangle selrect;203 int selrectRight = 0;204 205 switch(this.SelectedIndex) {206 case -1:207 break;208 case 0:209 selrect = this.GetTabRect(this.SelectedIndex);210 selrectRight = selrect.Right;211 e.Graphics.DrawLine(SystemPens.ControlLightLight, selrect.Left + 2, selrect.Bottom + 1, selrectRight - 2, selrect.Bottom + 1);212 break;213 default:214 selrect = this.GetTabRect(this.SelectedIndex);215 selrectRight = selrect.Right;216 e.Graphics.DrawLine(SystemPens.ControlLightLight, selrect.Left + 6 - selrect.Height, selrect.Bottom + 1, selrectRight - 2, selrect.Bottom + 1);217 break;218 }219 }220 221 private System.Drawing.Drawing2D.GraphicsPath GetPath(int index) {222 System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();223 path.Reset();224 225 Rectangle rect = this.GetTabRect(index);226 227 if (index == 0){228 path.AddLine(rect.Left + 1, rect.Bottom + 1, rect.Left + rect.Height, rect.Top + 2);229 path.AddLine(rect.Left + rect.Height + 4, rect.Top, rect.Right - 3, rect.Top);230 path.AddLine(rect.Right - 1, rect.Top + 2, rect.Right - 1, rect.Bottom + 1);231 } else {232 if (index == this.SelectedIndex) {233 path.AddLine(rect.Left + 1, rect.Top + 5, rect.Left + 4, rect.Top + 2);234 path.AddLine(rect.Left + 8, rect.Top, rect.Right - 3, rect.Top);235 path.AddLine(rect.Right - 1, rect.Top + 2, rect.Right - 1, rect.Bottom + 1);236 path.AddLine(rect.Right - 1, rect.Bottom + 1, rect.Left + 1, rect.Bottom + 1);237 } else {238 path.AddLine(rect.Left, rect.Top + 6, rect.Left + 4, rect.Top + 2);239 path.AddLine(rect.Left + 8, rect.Top, rect.Right - 3, rect.Top);240 path.AddLine(rect.Right - 1, rect.Top + 2, rect.Right - 1, rect.Bottom + 1);241 path.AddLine(rect.Right - 1, rect.Bottom + 1, rect.Left, rect.Bottom + 1);242 }243 244 }245 return path;246 }247 248 public enum TabControlDisplayManager {249 Default,250 Custom251 }252 253 [DllImport("user32.dll")]254 private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); 255 256 private const int WM_SETFONT = 0x30;257 private const int WM_FONTCHANGE = 0x1d;258 259 protected override void OnCreateControl()260 {261 base.OnCreateControl();262 this.OnFontChanged(EventArgs.Empty);263 } 264 265 protected override void OnFontChanged(EventArgs e)266 {267 base.OnFontChanged(e);268 IntPtr hFont = this.Font.ToHfont();269 SendMessage(this.Handle, WM_SETFONT, hFont, (IntPtr)(-1));270 SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);271 this.UpdateStyles();272 this.ItemSize = new Size(0, this.Font.Height + 2);273 }274 275 }276 }
从网上找到的代码,可以满足要求!