RoundPanel.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. using System.Drawing.Drawing2D;
  6. namespace NotePad.CustomerControls
  7. {
  8. public partial class RoundPanel : Panel
  9. {
  10. private Color _borderColor = Color.FromArgb(23, 169, 254);
  11. private int _radius = 10;
  12. private RoundStyle _roundeStyle;
  13. private const int WM_PAINT = 0xF;
  14. public RoundPanel()
  15. {
  16. InitializeComponent();
  17. }
  18. public enum RoundStyle
  19. {
  20. /// <summary>
  21. /// 四个角都不是圆角。
  22. /// </summary>
  23. None = 0,
  24. /// <summary>
  25. /// 四个角都为圆角。
  26. /// </summary>
  27. All = 1,
  28. /// <summary>
  29. /// 左边两个角为圆角。
  30. /// </summary>
  31. Left = 2,
  32. /// <summary>
  33. /// 右边两个角为圆角。
  34. /// </summary>
  35. Right = 3,
  36. /// <summary>
  37. /// 上边两个角为圆角。
  38. /// </summary>
  39. Top = 4,
  40. /// <summary>
  41. /// 下边两个角为圆角。
  42. /// </summary>
  43. Bottom = 5,
  44. }
  45. /// <summary>
  46. /// 建立带有圆角样式的路径。
  47. /// </summary>
  48. /// <param name="rect">用来建立路径的矩形。</param>
  49. /// <param name="_radius">圆角的大小。</param>
  50. /// <param name="style">圆角的样式。</param>
  51. /// <param name="correction">是否把矩形长宽减 1,以便画出边框。</param>
  52. /// <returns>建立的路径。</returns>
  53. GraphicsPath CreatePath(Rectangle rect, int radius, RoundStyle style, bool correction)
  54. {
  55. GraphicsPath path = new GraphicsPath();
  56. int radiusCorrection = correction ? 1 : 0;
  57. switch (style)
  58. {
  59. case RoundStyle.None:
  60. path.AddRectangle(rect);
  61. break;
  62. case RoundStyle.All:
  63. path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
  64. path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90);
  65. path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90);
  66. path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90);
  67. break;
  68. case RoundStyle.Left:
  69. path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
  70. path.AddLine(rect.Right - radiusCorrection, rect.Y, rect.Right - radiusCorrection, rect.Bottom - radiusCorrection);
  71. path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90);
  72. break;
  73. case RoundStyle.Right:
  74. path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90);
  75. path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90);
  76. path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y);
  77. break;
  78. case RoundStyle.Top:
  79. path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
  80. path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90);
  81. path.AddLine(rect.Right - radiusCorrection, rect.Bottom - radiusCorrection, rect.X, rect.Bottom - radiusCorrection);
  82. break;
  83. case RoundStyle.Bottom:
  84. path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90);
  85. path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90);
  86. path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y);
  87. break;
  88. }
  89. path.CloseFigure(); //这句很关键,缺少会没有左边线。
  90. return path;
  91. }
  92. [DefaultValue(typeof(Color), "23, 169, 254"), Description("控件边框颜色")]
  93. public Color BorderColor
  94. {
  95. get { return _borderColor; }
  96. set
  97. {
  98. _borderColor = value;
  99. base.Invalidate();
  100. }
  101. }
  102. [DefaultValue(typeof(int), "10"), Description("圆角弧度大小")]
  103. public int Radius
  104. {
  105. get { return _radius; }
  106. set
  107. {
  108. _radius = value;
  109. base.Invalidate();
  110. }
  111. }
  112. public RoundStyle RoundeStyle
  113. {
  114. get { return _roundeStyle; }
  115. set
  116. {
  117. _roundeStyle = value;
  118. base.Invalidate();
  119. }
  120. }
  121. protected override void WndProc(ref Message m)
  122. {
  123. try
  124. {
  125. base.WndProc(ref m);
  126. if (m.Msg == WM_PAINT)
  127. {
  128. if (this.Radius > 0)
  129. {
  130. using (Graphics g = Graphics.FromHwnd(this.Handle))
  131. {
  132. Rectangle r = new Rectangle();
  133. r.Width = this.Width;
  134. r.Height = this.Height;
  135. DrawBorder(g, r, this.RoundeStyle, this.Radius);
  136. }
  137. }
  138. }
  139. }
  140. catch (Exception ex)
  141. {
  142. MessageBox.Show(ex.Message);
  143. }
  144. }
  145. private void DrawBorder(Graphics g, Rectangle rect, RoundStyle roundStyle, int radius)
  146. {
  147. rect.Width -= 1;
  148. rect.Height -= 1;
  149. using (GraphicsPath path = CreatePath(rect, radius, roundStyle, false))
  150. {
  151. using (Pen pen = new Pen(this.BorderColor))
  152. {
  153. g.DrawPath(pen, path);
  154. }
  155. }
  156. }
  157. }
  158. }