CustomTabControl.cs 13 KB

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