绘制圆角(2)

今天推荐一下 https://github.com/kwonganding/winform.controls 里面的RoundRectangle类型,并实现圆角的绘制。

RoundRectangle的代码如下:

public class RoundRectangle
    {
        #region Initializes

        /// <summary>
        /// (构造函数).Initializes a new instance of the <see cref="RoundRectangle"/> class.
        /// </summary>
        /// <param name="roundRect">The roundRect.</param>
        /// <param name="radius">The radius.</param>
        /// User:Ryan  CreateTime:2011-07-19 16:59.
        public RoundRectangle(Rectangle rect, int radius)
            : this(rect, new CornerRadius(radius))
        {
        }

        /// <summary>
        /// (构造函数).Initializes a new instance of the <see cref="RoundRectangle"/> class.
        /// </summary>
        /// <param name="roundRect">The roundRect.</param>
        /// <param name="_CornerRadius">The corner radius.</param>
        /// User:Ryan  CreateTime:2011-07-19 16:59.
        public RoundRectangle(Rectangle rect, CornerRadius cornerRadius)
        {
            this.Rect = rect;
            this.CornerRadius = cornerRadius;
        }

        #endregion

        #region Properties

        /// <summary>
        /// 获取或者设置矩形区域
        /// </summary>
        /// <value>The roundRect.</value>
        /// User:Ryan  CreateTime:2011-07-19 16:59.
        public Rectangle Rect { get; set; }

        /// <summary>
        /// 获取或者设置圆角值
        /// </summary>
        /// <value>The corner radius.</value>
        /// User:Ryan  CreateTime:2011-07-19 16:59.
        public CornerRadius CornerRadius { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// 获取该圆角矩形的GraphicsPath对象(圆角使用Bezier曲线实现)
        /// </summary>
        /// <returns>
        /// Return a data(or instance) of GraphicsPath.
        /// </returns>
        /// User:Ryan  CreateTime:2011-07-20 11:52.
        public GraphicsPath ToGraphicsBezierPath()
        {
            GraphicsPath path = new GraphicsPath();
            int x = this.Rect.X;
            int y = this.Rect.Y;
            int w = this.Rect.Width;
            int h = this.Rect.Height;
            path.AddBezier(x, y + this.CornerRadius.TopLeft, x, y, x + this.CornerRadius.TopLeft, y, x + this.CornerRadius.TopLeft, y);
            path.AddLine(x + this.CornerRadius.TopLeft, y, x + w - this.CornerRadius.TopRight, y);
            path.AddBezier(x + w - this.CornerRadius.TopRight, y, x + w, y, x + w, y + this.CornerRadius.TopRight, x + w, y + this.CornerRadius.TopRight);
            path.AddLine(x + w, y + this.CornerRadius.TopRight, x + w, y + h - this.CornerRadius.BottomRight);
            path.AddBezier(x + w, y + h - this.CornerRadius.BottomRight, x + w, y + h, x + w - this.CornerRadius.BottomRight, y + h, x + w - this.CornerRadius.BottomRight, y + h);
            path.AddLine(x + w - this.CornerRadius.BottomRight, y + h, x + this.CornerRadius.BottomLeft, y + h);
            path.AddBezier(x + this.CornerRadius.BottomLeft, y + h, x, y + h, x, y + h - this.CornerRadius.BottomLeft, x, y + h - this.CornerRadius.BottomLeft);
            path.AddLine(x, y + h - this.CornerRadius.BottomLeft, x, y + this.CornerRadius.TopLeft);
            path.CloseFigure();
            return path;
        }

        /// <summary>
        /// 获取该圆角矩形的GraphicsPath对象(圆角使用矩形圆弧曲线曲线实现)
        /// </summary>
        /// <returns></returns>
        /// User:K.Anding  CreateTime:2011-7-31 23:25.
        public GraphicsPath ToGraphicsArcPath()
        {
            GraphicsPath path = new GraphicsPath();
            int x = this.Rect.X;
            int y = this.Rect.Y;
            int w = this.Rect.Width;
            int h = this.Rect.Height;
            path.AddArc(x, y, this.CornerRadius.TopLeft, this.CornerRadius.TopLeft, 180, 90);
            path.AddArc(x + w - this.CornerRadius.TopRight, y, this.CornerRadius.TopRight, this.CornerRadius.TopRight, 270, 90);
            path.AddArc(x + w - this.CornerRadius.BottomRight, y + h - this.CornerRadius.BottomRight,
                this.CornerRadius.BottomRight, this.CornerRadius.BottomRight,
                0, 90);
            path.AddArc(x, y + h - this.CornerRadius.BottomLeft, this.CornerRadius.BottomLeft, this.CornerRadius.BottomLeft, 90, 90);
            path.CloseFigure();
            return path;
        }

        /// <summary>
        /// 获取该圆角矩形的GraphicsPath对象(天使之翼的区域样式,主要用于Tabcontrol的标签样式)
        /// </summary>
        /// <returns>
        /// Return a data(or instance) of GraphicsPath.
        /// </returns>
        /// User:Ryan  CreateTime:2011-07-20 11:52.
        public GraphicsPath ToGraphicsAnglesWingPath()
        {
            GraphicsPath path = new GraphicsPath();
            int x = this.Rect.X;
            int y = this.Rect.Y;
            int w = this.Rect.Width;
            int h = this.Rect.Height;
            path.AddBezier(x, y + this.CornerRadius.TopLeft, x, y, x + this.CornerRadius.TopLeft, y, x + this.CornerRadius.TopLeft, y);
            path.AddLine(x + this.CornerRadius.TopLeft, y, x + w - this.CornerRadius.TopRight, y);
            path.AddBezier(x + w - this.CornerRadius.TopRight, y, x + w, y, x + w, y + this.CornerRadius.TopRight, x + w, y + this.CornerRadius.TopRight);
            path.AddLine(x + w, y + this.CornerRadius.TopRight, x + w, y + h - this.CornerRadius.BottomRight);
            path.AddBezier(x + w, y + h - this.CornerRadius.BottomRight, x + w, y + h, x + w + this.CornerRadius.BottomRight, y + h, x + w + this.CornerRadius.BottomRight, y + h);
            path.AddLine(x + w + this.CornerRadius.BottomRight, y + h, x - this.CornerRadius.BottomLeft, y + h);
            path.AddBezier(x - this.CornerRadius.BottomLeft, y + h, x, y + h, x, y + h - this.CornerRadius.BottomLeft, x, y + h - this.CornerRadius.BottomLeft);
            path.AddLine(x, y + h - this.CornerRadius.BottomLeft, x, y + this.CornerRadius.TopLeft);
            path.CloseFigure();
            return path;
        }

        #endregion
    }

该类型的作用是表示一个带圆角的矩形,我们可以通过矩形和CornerRadius类型构造对象,得到一个带圆角的GraphicsPath的封闭图形。

然后使用该类型我们可以使用Graphics的FillPath方法得到带圆角的图形。用户控件代码如下:

public class TestCornerRadiusDesigner:UserControl
    {
        CornerRadius radius;
        public TestCornerRadiusDesigner()
            :base()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.ResizeRedraw |
                     ControlStyles.UserPaint, true);

            radius = new CornerRadius(0);
        }
        [TypeConverterAttribute(typeof(CornerRadiusConverter))]
        public CornerRadius Radius
        {
            get { return radius; }
            set {
                radius = value;
                Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            if (radius.All != 0)
            {
                RoundRectangle roundRect = new RoundRectangle(this.ClientRectangle, radius);
                GraphicsPath regionRegion = roundRect.ToGraphicsBezierPath();
                this.Region = new System.Drawing.Region(regionRegion);//选择控件区域

                e.Graphics.FillPath(new SolidBrush(Color.Red), regionRegion);
            }
        }
    }

效果图如下:

如果调用开源项目中GDIHelper的InitializeGraphics方法提高一下绘制质量,圆角会更平滑一点。

posted on 2019-04-11 21:44  望蓝天  阅读(171)  评论(0编辑  收藏  举报

导航