zoukankan      html  css  js  c++  java
  • 绘制圆角(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方法提高一下绘制质量,圆角会更平滑一点。

  • 相关阅读:
    转 无障碍阅读 role aria-*
    (转)edm注意事项
    Spring IOC机制之使用注解配置bean
    Spring IOC机制使用SpEL
    使用Spring IOC容器引用外部属性文件
    如何将属性文件中的值保存到类中
    基于XML的类的属性的装配
    Java——事务
    Eclipse中使用Spring IOC容器的具体方法
    Java之批处理的实现
  • 原文地址:https://www.cnblogs.com/jianIsTheBest/p/10692816.html
Copyright © 2011-2022 走看看