重寫Label控件Demo

重寫帶邊框的圓角矩形label控件,效果如下圖

實現如下:

   public enum Direction
    {
        Top,
        Left,
        Right,
        Bottom
    }

    public static class GraphicsPathExtension
    {
        /// <summary>
        /// 創建正多邊形
        /// </summary>
        public static GraphicsPath CreateRegularPolygon(this Graphics g, float x, float y, float r, int num)
        {
            var path = new GraphicsPath();
            var p1 = new PointF(x, y - r);
            for (var i = 1; i < num; i++)
            {
                var d = PI / 2 - PI * 2 / num * i;
                var p2 = new PointF(x + (float)(r * Cos(d)), y - (float)(r * Sin(d)));
                path.AddLine(p1, p2);
                p1 = p2;
            }
            return path;
        }

        /// <summary>
        /// 創建一個箭頭指向特定方向的等邊三角形,且與指定矩形的中心重合
        /// </summary>
        public static GraphicsPath CreateTrianglePath(this Graphics g, RectangleF rect, float f, Direction direction)
        {
            float width = rect.Width < rect.Height ? rect.Width : rect.Height;
            PointF p1 = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2),
                   p2 = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2),
                   p3 = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);

            float d = width * f;
            float sqrt = (float)Sqrt(3);
            if (direction == Direction.Left)
            {
                p1.X -= 2 * d;

                p2.X += d;
                p2.Y += d * sqrt;

                p3.X += d;
                p3.Y -= d * sqrt;
            }
            else if (direction == Direction.Right)
            {
                p1.X += 2 * d;

                p2.X -= d;
                p2.Y += d * sqrt;

                p3.X -= d;
                p3.Y += d * sqrt;
            }
            else if (direction == Direction.Top)
            {
                p1.Y -= 2 * d;

                p2.X -= d * sqrt;
                p2.Y += d;

                p3.X += d * sqrt;
                p3.Y += d;
            }
            else
            {
                p1.Y += 2 * d;

                p2.X -= d * sqrt;
                p2.Y -= d;

                p3.X += d * sqrt;
                p3.Y -= d;
            }

            var path = new GraphicsPath();
            path.AddLines(new[] { p1, p2, p3 });
            return path;
        }

        /// <summary>
        /// 創建圓角矩形路徑
        /// </summary>
        public static GraphicsPath CreateRoundedRectanglePath(this Graphics g, Rectangle rect, int cornerRadius)
        {
            var roundedRect = new GraphicsPath();
            if (cornerRadius > 0)
            {
                roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
            }
            roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
            if (cornerRadius > 0)
            {
                roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
            }
            roundedRect.AddLine(rect.Right, Min(rect.Y + cornerRadius * 2, rect.Y + rect.Height / 2), rect.Right, Max(rect.Y + rect.Height - cornerRadius * 2, rect.Y + rect.Height / 2));
            if (cornerRadius > 0)
            {
                roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
            }
            roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom);
            if (cornerRadius > 0)
            {
                roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
            }
            roundedRect.AddLine(rect.X, Max(rect.Bottom - cornerRadius * 2, rect.Y + rect.Height / 2), rect.X, Min(rect.Y + cornerRadius * 2, rect.Y + rect.Height / 2));
            roundedRect.CloseFigure();
            return roundedRect;
        }

        /// <summary>
        /// 創建圓角矩形路徑(r1:左上,r2:右上,r3:右下,r4:左下)
        /// </summary>
        public static GraphicsPath CreateRoundedRectanglePath(this Graphics g, Rectangle rect, int r1, int r2, int r3, int r4)
        {
            var roundedRect = new GraphicsPath();
            if (r1 > 0)
            {
                roundedRect.AddArc(rect.X, rect.Y, r1 * 2, r1 * 2, 180, 90);
            }
            roundedRect.AddLine(rect.X + r1, rect.Y, rect.Right - r2 * 2, rect.Y);
            if (r2 > 0)
            {
                roundedRect.AddArc(rect.X + rect.Width - r2 * 2, rect.Y, r2 * 2, r2 * 2, 270, 90);
            }
            roundedRect.AddLine(rect.Right, Min(rect.Y + r2 * 2, rect.Y + rect.Height / 2), rect.Right, Max(rect.Y + rect.Height - r3 * 2, rect.Y + rect.Height / 2));
            if (r3 > 0)
            {
                roundedRect.AddArc(rect.X + rect.Width - r3 * 2, rect.Y + rect.Height - r3 * 2, r3 * 2, r3 * 2, 0, 90);
            }
            roundedRect.AddLine(rect.Right - r3 * 2, rect.Bottom, rect.X + r3 * 2, rect.Bottom);
            if (r4 > 0)
            {
                roundedRect.AddArc(rect.X, rect.Bottom - r4 * 2, r4 * 2, r4 * 2, 90, 90);
            }
            roundedRect.AddLine(rect.X, Max(rect.Bottom - r4 * 2, rect.Y + rect.Height / 2), rect.X, Min(rect.Y + r1 * 2, rect.Y + rect.Height / 2));
            roundedRect.CloseFigure();
            return roundedRect;
        }
    }

 

/// <summary>
    /// 帶邊框的label
    /// </summary>
    public class UcLabel : Label
    {
        #region 數據屬性
        /// <summary>
        ///     邊框的寬度
        /// </summary>
        [Category("Border")]
        public int BorderWidth { get { return borderWidth; } set { borderWidth = value; Invalidate(); } }
        private int borderWidth = 1;

        /// <summary>
        ///     邊框顏色
        /// </summary>
        [Category("Border")]
        public Color BorderColor { get { return borderColor; } set { borderColor = value; Invalidate(); } }
        private Color borderColor = Color.FromArgb(95, 132, 205);


        /// <summary>
        ///     邊框樣式
        /// </summary>
        [Category("Border")]
        public DashStyle BorderDashStyle { get { return borderDashStyle; } set { borderDashStyle = value; Invalidate(); } }
        private DashStyle borderDashStyle = DashStyle.Solid;

        /// <summary>
        ///     是否顯示邊框
        /// </summary>
        [Category("Border")]
        public bool ShowBorder
        {
            get
            {
                return showBorder;
            }
            set
            {
                showBorder = value;
                if (showBorder)
                {
                    BorderStyle = BorderStyle.None;
                }
                Invalidate();
            }
        }
        private bool showBorder = false;

        /// <summary>
        ///     圓角
        /// </summary>
        [Category("Border")]
        public int Radius
        {
            get { return radius; }
            set { radius = value < 0 ? 0 : value; Invalidate(); }
        }
        private int radius = 0;
        #endregion

        #region 構造函數
        public UcLabel()
        {
        }
        #endregion

        #region 重繪

        /// <summary>
        /// 引發 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
        /// </summary>
        /// <param name="e">包含事件數據的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (showBorder)
            {
                if (showBorder)
                {
                    Graphics graphics = e.Graphics;
                    graphics.SmoothingMode = SmoothingMode.AntiAlias;
                    graphics.CompositingQuality = CompositingQuality.HighQuality;

                    var pen = new Pen(borderColor, borderWidth);
                    pen.DashStyle = borderDashStyle;

                    var rect = new Rectangle(0, 0, Width - borderWidth, Height - borderWidth);
                    if (radius > 0)
                    {
                        var path = graphics.CreateRoundedRectanglePath(rect, Radius);
                        graphics.DrawPath(pen, path);
                    }
                    else
                    {
                        graphics.DrawRectangle(pen, rect);
                    }
                }
            }
        }

        #endregion
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章