using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace LC.Component { public class cpPanel : System.Windows.Forms.Panel { private Color _borderColor = Color.FromArgb(23, 169, 254); private int _radius = 10; private RoundStyle _roundeStyle; private const int WM_PAINT = 0xF; public cpPanel() : base() { } /// <summary> /// 建立圓角路徑的樣式。 /// </summary> public enum RoundStyle { /// <summary> /// 四個角都不是圓角。 /// </summary> None = 0, /// <summary> /// 四個角都為圓角。 /// </summary> All = 1, /// <summary> /// 左邊兩個角為圓角。 /// </summary> Left = 2, /// <summary> /// 右邊兩個角為圓角。 /// </summary> Right = 3, /// <summary> /// 上邊兩個角為圓角。 /// </summary> Top = 4, /// <summary> /// 下邊兩個角為圓角。 /// </summary> Bottom = 5, } /// <summary> /// 建立帶有圓角樣式的路徑。 /// </summary> /// <param name="rect">用來建立路徑的矩形。</param> /// <param name="_radius">圓角的大小。</param> /// <param name="style">圓角的樣式。</param> /// <param name="correction">是否把矩形長寬減 1,以便畫出邊框。</param> /// <returns>建立的路徑。</returns> GraphicsPath CreatePath(Rectangle rect, int radius, RoundStyle style, bool correction) { GraphicsPath path = new GraphicsPath(); int radiusCorrection = correction ? 1 : 0; switch (style) { case RoundStyle.None: path.AddRectangle(rect); break; case RoundStyle.All: path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90); path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90); path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90); break; case RoundStyle.Left: path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); path.AddLine(rect.Right - radiusCorrection, rect.Y, rect.Right - radiusCorrection, rect.Bottom - radiusCorrection); path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90); break; case RoundStyle.Right: path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90); path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90); path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y); break; case RoundStyle.Top: path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90); path.AddLine(rect.Right - radiusCorrection, rect.Bottom - radiusCorrection, rect.X, rect.Bottom - radiusCorrection); break; case RoundStyle.Bottom: path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90); path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90); path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); break; } path.CloseFigure(); //這句很關鍵,缺少會沒有左邊線。 return path; } [DefaultValue(typeof(Color), "23, 169, 254"), Description("控件邊框顏色")] public Color BorderColor { get { return _borderColor; } set { _borderColor = value; base.Invalidate(); } } [DefaultValue(typeof(int), "10"), Description("圓角弧度大小")] public int Radius { get { return _radius; } set { _radius = value; base.Invalidate(); } } public RoundStyle RoundeStyle { get { return _roundeStyle; } set { _roundeStyle = value; base.Invalidate(); } } protected override void WndProc(ref Message m) { try { base.WndProc(ref m); if (m.Msg == WM_PAINT) { if (this.Radius > 0) { using (Graphics g = Graphics.FromHwnd(this.Handle)) { Rectangle r = new Rectangle(); r.Width = this.Width; r.Height = this.Height; DrawBorder(g, r, this.RoundeStyle, this.Radius); } } } } catch(Exception ex) { MessageBox.Show(ex.Message); } } private void DrawBorder(Graphics g, Rectangle rect, RoundStyle roundStyle, int radius) { rect.Width -= 1; rect.Height -= 1; using (GraphicsPath path = CreatePath(rect, radius, roundStyle, false)) { using (Pen pen = new Pen(this.BorderColor)) { g.DrawPath(pen, path); } } } } }