CustomTabControl.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Runtime.InteropServices;
  5. using System.Windows.Forms;
  6. namespace UAS_MES_NEW.CustomControl
  7. {
  8. [ToolboxBitmap(typeof(TabControl))]
  9. public partial class CustomTabControl : TabControl
  10. {
  11. const int CLOSE_SIZE = 16;
  12. // Bitmap image = new Bitmap("../../Resources/close.png");
  13. public CustomTabControl() : base()
  14. {
  15. //首先判断选择的是什么样式
  16. if (this._DisplayManager.Equals(TabControlDisplayManager.Custom))
  17. {
  18. //是否由系统绘制,true表示自行绘制
  19. this.SetStyle(ControlStyles.UserPaint, true);
  20. this.ItemSize = new Size(0, 15);
  21. this.Padding = new Point(9, 0);
  22. }
  23. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  24. this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
  25. this.SetStyle(ControlStyles.ResizeRedraw, true);
  26. this.ResizeRedraw = true;
  27. }
  28. //用户选择样式
  29. TabControlDisplayManager _DisplayManager = TabControlDisplayManager.Custom;
  30. [System.ComponentModel.DefaultValue(typeof(TabControlDisplayManager), "Custom")]
  31. public TabControlDisplayManager DisplayManager
  32. {
  33. get
  34. {
  35. return this._DisplayManager;
  36. }
  37. set
  38. {
  39. if (this._DisplayManager != value)
  40. {
  41. if (this._DisplayManager.Equals(TabControlDisplayManager.Custom))
  42. {
  43. this.SetStyle(ControlStyles.UserPaint, true);
  44. this.ItemSize = new Size(0, 15);
  45. this.Padding = new Point(9, 0);
  46. }
  47. else
  48. {
  49. this.ItemSize = new Size(0, 0);
  50. this.Padding = new Point(6, 3);
  51. this.SetStyle(ControlStyles.UserPaint, false);
  52. }
  53. }
  54. }
  55. }
  56. protected override void OnPaintBackground(PaintEventArgs pevent)
  57. {
  58. //是否绘制该控件
  59. if (this.DesignMode == true)
  60. {
  61. LinearGradientBrush backBrush = new LinearGradientBrush(
  62. this.Bounds,
  63. SystemColors.ControlLightLight,
  64. SystemColors.ControlLight,
  65. LinearGradientMode.Vertical);
  66. pevent.Graphics.FillRectangle(backBrush, this.Bounds);
  67. backBrush.Dispose();
  68. }
  69. else
  70. {
  71. this.PaintTransparentBackground(pevent.Graphics, this.ClientRectangle);
  72. }
  73. }
  74. protected void PaintTransparentBackground(Graphics g, Rectangle clipRect)
  75. {
  76. if ((this.Parent != null))
  77. {
  78. clipRect.Offset(this.Location);
  79. PaintEventArgs e = new PaintEventArgs(g, clipRect);
  80. GraphicsState state = g.Save();
  81. g.SmoothingMode = SmoothingMode.HighSpeed;
  82. try
  83. {
  84. g.TranslateTransform((float)-this.Location.X, (float)-this.Location.Y);
  85. this.InvokePaintBackground(this.Parent, e);
  86. this.InvokePaint(this.Parent, e);
  87. }
  88. finally
  89. {
  90. g.Restore(state);
  91. clipRect.Offset(-this.Location.X, -this.Location.Y);
  92. }
  93. }
  94. else
  95. {
  96. LinearGradientBrush backBrush = new LinearGradientBrush(this.Bounds, SystemColors.ControlLightLight, SystemColors.ControlLight, System.Drawing.Drawing2D.LinearGradientMode.Vertical);
  97. g.FillRectangle(backBrush, this.Bounds);
  98. backBrush.Dispose();
  99. }
  100. }
  101. //将组件绘制到界面,加载的时候执行
  102. protected override void OnPaint(PaintEventArgs e)
  103. {
  104. // Paint the Background
  105. this.PaintTransparentBackground(e.Graphics, this.ClientRectangle);
  106. //绘制所有的tabPage
  107. this.PaintAllTheTabs(e);
  108. //绘制tabPage的边框
  109. this.PaintTheTabPageBorder(e);
  110. //选中的tabPage去除边框
  111. this.PaintTheSelectedTab(e);
  112. }
  113. //也是调用PaintTab循环绘制出来的
  114. private void PaintAllTheTabs(System.Windows.Forms.PaintEventArgs e)
  115. {
  116. if (this.TabCount > 0)
  117. {
  118. for (int index = 0; index < this.TabCount; index++)
  119. {
  120. this.PaintTab(e, index);
  121. }
  122. }
  123. }
  124. //绘制tab
  125. private void PaintTab(PaintEventArgs e, int index)
  126. {
  127. GraphicsPath path = this.GetPath(index);
  128. this.PaintTabBackground(e.Graphics, index, path);
  129. this.PaintTabBorder(e.Graphics, index, path);
  130. this.PaintTabText(e.Graphics, index);
  131. this.PaintTabImage(e.Graphics, index);
  132. }
  133. private void PaintTabBackground(Graphics graph, int index, GraphicsPath path)
  134. {
  135. Rectangle rect = this.GetTabRect(index);
  136. Brush buttonBrush =
  137. new LinearGradientBrush(
  138. rect,
  139. SystemColors.ControlLightLight,
  140. SystemColors.ControlLight,
  141. LinearGradientMode.Vertical);
  142. if (index == this.SelectedIndex)
  143. {
  144. buttonBrush = new SolidBrush(SystemColors.ControlLightLight);
  145. }
  146. graph.FillPath(buttonBrush, path);
  147. buttonBrush.Dispose();
  148. }
  149. //绘制边框
  150. private void PaintTabBorder(Graphics graph, int index, GraphicsPath path)
  151. {
  152. Pen borderPen = new Pen(SystemColors.ControlDark);
  153. if (index == this.SelectedIndex)
  154. {
  155. borderPen = new Pen(ThemedColors.ToolBorder);
  156. }
  157. graph.DrawPath(borderPen, path);
  158. borderPen.Dispose();
  159. }
  160. private void PaintTabImage(System.Drawing.Graphics graph, int index)
  161. {
  162. Image tabImage = null;
  163. if (this.TabPages[index].ImageIndex > -1 && this.ImageList != null)
  164. {
  165. tabImage = this.ImageList.Images[this.TabPages[index].ImageIndex];
  166. }
  167. else if (this.TabPages[index].ImageKey.Trim().Length > 0 && this.ImageList != null)
  168. {
  169. tabImage = this.ImageList.Images[this.TabPages[index].ImageKey];
  170. }
  171. if (tabImage != null)
  172. {
  173. Rectangle rect = this.GetTabRect(index);
  174. graph.DrawImage(tabImage, rect.Right - rect.Height + 5, 4, rect.Height - 2, rect.Height - 2);
  175. }
  176. }
  177. //绘制文字
  178. private void PaintTabText(Graphics graph, int index)
  179. {
  180. Rectangle rect = this.GetTabRect(index);
  181. Rectangle rect2 = new Rectangle(rect.Left + 8, rect.Top + 1, rect.Width - 6, rect.Height);
  182. if (index == 0)
  183. {
  184. rect2 = new Rectangle(rect.Left + rect.Height, rect.Top + 1, rect.Width - rect.Height, rect.Height);
  185. }
  186. else
  187. {
  188. rect2 = new Rectangle(rect.Left + rect.Height - 5, rect.Top + 1, rect.Width - rect.Height + 5, rect.Height);
  189. }
  190. string tabtext = this.TabPages[index].Text;
  191. StringFormat format = new StringFormat();
  192. //字符串的水平和垂直对齐方式
  193. format.Alignment = StringAlignment.Near;
  194. format.LineAlignment = StringAlignment.Center;
  195. format.Trimming = StringTrimming.EllipsisCharacter;
  196. Brush forebrush = null;
  197. if (this.TabPages[index].Enabled == false)
  198. {
  199. forebrush = SystemBrushes.ControlDark;
  200. }
  201. else
  202. {
  203. forebrush = SystemBrushes.ControlText;
  204. }
  205. Font tabFont = this.Font;
  206. //选中了之后文本加粗
  207. if (index == this.SelectedIndex)
  208. {
  209. tabFont = new Font(this.Font, FontStyle.Bold);
  210. if (index == 0)
  211. {
  212. //第一个的时候做特殊处理,调整文字的位置
  213. rect2 = new Rectangle(rect.Left + rect.Height, rect.Top + 1, rect.Width - rect.Height + 5, rect.Height);
  214. }
  215. }
  216. graph.DrawString(tabtext, tabFont, forebrush, rect2, format);
  217. }
  218. //绘制边框
  219. private void PaintTheTabPageBorder(System.Windows.Forms.PaintEventArgs e)
  220. {
  221. if (this.TabCount > 0)
  222. {
  223. Rectangle borderRect = this.TabPages[0].Bounds;
  224. borderRect.Inflate(1, 1);
  225. ControlPaint.DrawBorder(e.Graphics, borderRect, ThemedColors.ToolBorder, ButtonBorderStyle.Solid);
  226. }
  227. }
  228. //选中tabPage的时候去除下边框
  229. private void PaintTheSelectedTab(System.Windows.Forms.PaintEventArgs e)
  230. {
  231. Rectangle selrect;
  232. int selrectRight = 0;
  233. switch (this.SelectedIndex)
  234. {
  235. case -1:
  236. break;
  237. case 0:
  238. selrect = this.GetTabRect(this.SelectedIndex);
  239. selrectRight = selrect.Right;
  240. e.Graphics.DrawLine(SystemPens.ControlLightLight, selrect.Left + 2, selrect.Bottom + 1, selrectRight + 8, selrect.Bottom + 1);
  241. break;
  242. default:
  243. selrect = this.GetTabRect(this.SelectedIndex);
  244. selrectRight = selrect.Right;
  245. e.Graphics.DrawLine(SystemPens.ControlLightLight, selrect.Left + 11, selrect.Bottom + 1, selrectRight + 5, selrect.Bottom + 1);
  246. break;
  247. }
  248. }
  249. //绘制tabPage的形状
  250. private GraphicsPath GetPath(int index)
  251. {
  252. GraphicsPath path = new GraphicsPath();
  253. path.Reset();
  254. Rectangle rect = this.GetTabRect(index);
  255. if (index == 0)
  256. { //画线的地方,采用两个点相连的方式,需要设置x1,y1,x2,y2四个坐标
  257. path.AddLine(rect.Left + 1, rect.Bottom + 1, rect.Left + rect.Height, rect.Top + 2);
  258. path.AddLine(rect.Left + rect.Height + 4, rect.Top, rect.Right + 8, rect.Top);
  259. path.AddLine(rect.Right + 10, rect.Top + 2, rect.Right + 10, rect.Bottom + 1);
  260. }
  261. else
  262. {
  263. if (index == this.SelectedIndex)
  264. {
  265. path.AddLine(rect.Left + 12, rect.Top + 5, rect.Left + 15, rect.Top + 2);
  266. path.AddLine(rect.Left + 19, rect.Top, rect.Right + 8, rect.Top);
  267. path.AddLine(rect.Right + 10, rect.Top + 2, rect.Right + 10, rect.Bottom + 1);
  268. path.AddLine(rect.Right + 10, rect.Bottom + 1, rect.Left + 11, rect.Bottom + 1);
  269. }
  270. else
  271. {
  272. path.AddLine(rect.Left + 12, rect.Top + 5, rect.Left + 15, rect.Top + 2);
  273. path.AddLine(rect.Left + 19, rect.Top, rect.Right + 8, rect.Top);
  274. path.AddLine(rect.Right + 10, rect.Top + 2, rect.Right + 10, rect.Bottom + 1);
  275. path.AddLine(rect.Right + 10, rect.Bottom + 1, rect.Left + 11, rect.Bottom + 1);
  276. }
  277. }
  278. return path;
  279. }
  280. //枚举类型 多个风格的界面
  281. public enum TabControlDisplayManager
  282. {
  283. Default,
  284. Custom
  285. }
  286. [DllImport("user32.dll")]
  287. private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
  288. private const int WM_SETFONT = 0x30;
  289. private const int WM_FONTCHANGE = 0x1d;
  290. //在启动时
  291. protected override void OnCreateControl()
  292. {
  293. base.OnCreateControl();
  294. this.OnFontChanged(EventArgs.Empty);
  295. }
  296. //设置字体后自适应改变宽高
  297. protected override void OnFontChanged(EventArgs e)
  298. {
  299. base.OnFontChanged(e);
  300. IntPtr hFont = this.Font.ToHfont();
  301. SendMessage(this.Handle, WM_SETFONT, hFont, (IntPtr)(-1));
  302. SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
  303. this.UpdateStyles();
  304. this.ItemSize = new Size(0, this.Font.Height + 2);
  305. }
  306. }
  307. }