程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#矩形圓角繪制改進版

C#矩形圓角繪制改進版

編輯:關於C#

一、前言

上一篇繪制矩形圓角的方式不夠完善,感覺寫的太過於復雜,將簡單的問題復雜化了,本文對此進行了相應的改進,增強對各個圓角的半徑的控制。繪制後的圓角效果圖如下:

二、圓角半徑設計

對於矩行而言,圓角分為左上角、右上角、左下角和右下角。每一個角都會存在相應的半徑,用於控制每一個圓角的繪制。設計如下:

public struct ArcRadius
    {
        private int _rightBottom;
        private int _rightTop;
        private int _leftBottom;
        private int _leftTop;
    
        public static readonly ArcRadius Empty =new ArcRadius(0);
    
        public ArcRadius(int radiusLength)
        {
            if (radiusLength < 0)
            {
                radiusLength = 0;
            }
    
            this._rightBottom = this._rightTop = this._leftBottom = this._leftTop = radiusLength;
        }
    
        public ArcRadius(int leftTop, int rightTop, int leftBottom, int rightBottom)
        {
            this._rightBottom = rightBottom < 0 ? 0 : rightBottom;
            this._rightTop = rightTop < 0 ? 0 : rightTop;
            this._leftBottom = leftBottom < 0 ? 0 : leftBottom;
            this._leftTop = leftTop < 0 ? 0 : leftTop;
        }
    
        private bool IsAllEqual()
        {
            return ((this.RightBottom == this.RightTop)
                 && (this.RightBottom == this.LeftBottom))
                 && (this.RightBottom == this.LeftTop);
        }
    
        public int All
        {
            get
            {
                if (!IsAllEqual())
                {
                    return -1;
                }
    
                return this.RightBottom;
            }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
    
                this.RightBottom = this.RightTop = this.LeftBottom = this.LeftTop = value;
            }
        }
    
        public int LeftTop
        {
            get
            {
                return this._leftTop;
            }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
    
                this._leftTop = value;
            }
        }
     
        public int RightTop
        {
            get
            {
                return this._rightTop;
            }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
    
                this._rightTop = value;
            }
        }
           
        public int LeftBottom
        {
            get
            {
                return this._leftBottom;
            }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
    
                this._leftBottom = value;
            }
        }
    
        public int RightBottom
        {
            get
            {
                return this._rightBottom;
            }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
    
                this._rightBottom = value;
            }
        }
    
        public static bool operator ==(ArcRadius p1, ArcRadius p2)
        {
            return ((((p1.RightTop == p2.RightTop) 
                && (p1.RightBottom == p2.RightBottom))
                && (p1.LeftBottom == p2.LeftBottom)) 
                && (p1.LeftTop == p2.LeftTop));
        }
    
        public static bool operator !=(ArcRadius p1, ArcRadius p2)
        {
            return !(p1 == p2);
        }
    
        public override string ToString()
        {
            return LeftTop + ", " + RightTop + ", " + LeftBottom + ", " + RightBottom;
        }
    }

三、GraphicsPathHelper類

主要包括如下兩個方法:

public static void DrawRoundRectangle(Graphics g,RoundRectangleArg arg)           用於繪制帶有圓角的矩形

public static GraphicsPath CreateRoundPath(Rectangle rect, ArcRadius arcRadius)  用於創建圓角路徑,對上文的改進主要在於此方法。不需要對圓角組合進行判斷,只需要根據每一個圓角的半徑是否大於0而進行相應的圓角繪制。

public static class GraphicsPathHelper
    {
        public static void DrawRoundRectangle(Graphics g,RoundRectangleArg arg)
        {
            if (g == null || arg.Rectangle.Width == 0 || arg.Rectangle.Height == 0)
            {
                return;
            }
    
            using (SmoothingModeGraphics smoothingMode = new SmoothingModeGraphics(g, SmoothingMode.AntiAlias))
            {
                using (var path = CreateRoundPath(arg.Rectangle, arg.ArcRadius))
                {
                    if (arg.DrawBackground)
                    {
                        using (var fillBrush = new LinearGradientBrush(
                            arg.Rectangle, arg.StartColor, arg.EndColor, arg.LinearGradientMode))
                        {
                            var blend = new ColorBlend(2);
                            blend.Positions[0] = 0.0f;
                            blend.Positions[1] = 1.0f;
                            blend.Colors[0] = arg.StartColor;
                            blend.Colors[1] = arg.EndColor;
                            fillBrush.InterpolationColors = blend;
                            g.FillPath(fillBrush, path);
                        }
                    }
    
                    if (arg.DrawBorder)
                    {
                        using (var pen = new Pen(new SolidBrush(arg.BorderColor), arg.BorderWidth))
                            g.DrawPath(pen, path);
                    }
    
                    if (arg.DrawInnerBorder)
                    {
                        Rectangle rectangle = arg.Rectangle;
                        rectangle.Inflate(-2, -2);
                        var innerPath = CreateRoundPath(rectangle, arg.ArcRadius);
    
                        using (var pen = new Pen(new SolidBrush(arg.InnerBorderColor), arg.InnerBorderWidth))
                        {
                            g.DrawPath(pen, innerPath);
                        }
                    }
                }
            }
        }
    
        public static GraphicsPath CreateRoundPath(Rectangle rect, ArcRadius arcRadius)
        {
            var path = new GraphicsPath();
    
            if (rect.Width == 0 || rect.Height == 0)
            {
                return path;
            }
    
            if (arcRadius.LeftTop > 0)
            {
                path.AddArc(
                    rect.Left, rect.Top, arcRadius.LeftTop, arcRadius.LeftTop, 180, 90);
            }
    
            path.AddLine(new Point(rect.Left + arcRadius.LeftTop, rect.Top),
                         new Point(rect.Right - arcRadius.RightTop, rect.Top));
    
            if (arcRadius.RightTop > 0)
            {
                path.AddArc(rect.Right - arcRadius.RightTop, rect.Top,
                    arcRadius.RightTop, arcRadius.RightTop, -90, 90);
            }
    
            path.AddLine(new Point(rect.Right, rect.Top + arcRadius.RightTop),
                         new Point(rect.Right, rect.Bottom - arcRadius.RightBottom));
    
            if (arcRadius.RightBottom > 0)
            {
                path.AddArc(rect.Right - arcRadius.RightBottom, rect.Bottom - arcRadius.RightBottom,
                    arcRadius.RightBottom, arcRadius.RightBottom, 0, 90);
            }
    
            path.AddLine(new Point(rect.Right - arcRadius.RightBottom, rect.Bottom),
                         new Point(rect.Left + arcRadius.LeftBottom, rect.Bottom));
    
            if (arcRadius.LeftBottom > 0)
            {
                path.AddArc(rect.Left, rect.Bottom - arcRadius.LeftBottom,
                    arcRadius.LeftBottom, arcRadius.LeftBottom, 90, 90);
            }
    
            path.AddLine(new Point(rect.Left, rect.Bottom - arcRadius.LeftBottom),
                         new Point(rect.Left, rect.Top + arcRadius.LeftTop));
    
            path.CloseFigure();
    
            return path;
        }
    }

四、應用

應用的話比較簡單,只需要設置RoundRectangleArg參數,然後調用GraphicsPathHelper.DrawRoundRectangle即可。

RoundRectangleArg arg = new RoundRectangleArg();

arg.Rectangle = rectangle;

arg.ArcRadius = new ArcRadius((int)this.numericLeftBottomRadiuds.Value, (int)this.numericRightTopRadiuds.Value,

(int)this.numericLeftTopRadiuds.Value, (int)this.numericRightBottomRadiuds.Value);

arg.BorderColor = Color.FromName((this.cboBorderColors.SelectedItem ?? string.Empty).ToString());

arg.InnerBorderColor = Color.FromName((this.cboInnerBorderColors.SelectedItem ?? string.Empty).ToString());

arg.StartColor = Color.FromName((this.cboStartColors.SelectedItem ?? string.Empty).ToString());

arg.EndColor = Color.FromName((this.cboEndColors.SelectedItem ?? string.Empty).ToString());

arg.LinearGradientMode = gradientMode;

arg.DrawInnerBorder = this.ckbDrawInnerBorder.Checked;

arg.DrawBorder = this.ckbDrawBorder.Checked;

arg.DrawBackground = this.ckbDrawBg.Checked;

arg.BorderWidth = (int)this.numericBorderWidth.Value;

arg.InnerBorderWidth = (int)this.numericInnerBorderWidth.Value;

GraphicsPathHelper.DrawRoundRectangle(graphic, arg);

五、總結

前一篇的隨筆主要是應用位操作來處理枚舉,將問題復雜化了。本文進行了相應的改進,代碼相對來說更加清晰與簡潔。 改進版的源碼下載如下:

源碼下載:矩形圓角繪制改進版

http://www.cnblogs.com/jasenkin/admin/矩形圓角繪制改進版

作者:JasenKin

出處:http://www.cnblogs.com/jasenkin/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved