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

C# GDI+如何繪制矩行的圓角

編輯:關於C#

一、前言

本文主要介紹C# GDI+如何繪制矩行的圓角,其中涉及到如何使用位操作來處理組合的技巧。GDI+的本質在於,它能夠替代開發人員實現與顯示器及其它外部設備的交互。對於控件美化而言,需要達到自己期望的效果,GDI+必不可少。繪制後的圓角效果圖如下:

二、圓角枚舉與相應組合處理設計

對於矩行而言,圓角分為左上角、右上角、左下角和右下角。組合情況就分為無圓角、一個圓角、二個圓角、三個圓角以及四個圓角。枚舉需要滿足該組合情況,沒必要在枚舉中將 全部組合列出,只需要通過位操作就能計算出屬於哪種組合。枚舉類設計如下:

[Flags]
    public enum RoundStyle
    {     
        None = 0,     
        TopLeft = 1,
        TopRight = 2,
        BottomLeft = 4,
        BottomRight = 8 ,
        All = TopLeft | TopRight | BottomLeft | BottomRight
    }

矩行的圓角所有組合情況如下:

RoundStyle.None

RoundStyle.All

RoundStyle.BottomLeft

RoundStyle.BottomRight

RoundStyle.TopLeft

RoundStyle.TopRightRoundStyle.BottomRight | RoundStyle.BottomLeft

RoundStyle.BottomRight | RoundStyle.TopRight

RoundStyle.TopRight | RoundStyle.TopLeft

RoundStyle.BottomLeft | RoundStyle.TopLeft

RoundStyle.BottomRight | RoundStyle.TopLeft

RoundStyle.TopRight | RoundStyle.BottomLeftRoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopLeft

RoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopRight

RoundStyle.BottomLeft | RoundStyle.TopLeft | RoundStyle.TopRight

RoundStyle.BottomRight | RoundStyle.TopRight | RoundStyle.TopLeft

對於每一種組合,必須提供相應的操作來執行路徑計算,這主要是因為GraphicsPath的路徑是有順序的。因此所有組合對應的處理方式如下:

private static IDictionary<RoundStyle, Action<GraphicsPath, Rectangle, int, int>>
            CreateRoundStylesEventContainer()
        {
            var container = new Dictionary<RoundStyle, Action<GraphicsPath, Rectangle, int, int>>();
    
            container.Add(RoundStyle.None, (path, rect, radius, radiusAdjustment) => { path.AddRectangle(rect); });
            container.Add(RoundStyle.All, AddAllRoundStyle);
    
            container.Add(RoundStyle.BottomLeft, AddBottomLeftRoundStyle);
            container.Add(RoundStyle.BottomRight, AddBottomRightRoundStyle);
            container.Add(RoundStyle.TopLeft, AddTopLeftRoundStyle);
            container.Add(RoundStyle.TopRight, AddTopRightRoundStyle);
    
            container.Add(RoundStyle.BottomRight | RoundStyle.BottomLeft, AddBottomRightAndBottomLeftRoundStyle);
            container.Add(RoundStyle.BottomRight | RoundStyle.TopRight, AddBottomRightAndTopRightRoundStyle);
            container.Add(RoundStyle.TopRight | RoundStyle.TopLeft, AddTopRightAndTopLeftRoundStyle);
            container.Add(RoundStyle.BottomLeft | RoundStyle.TopLeft, AddBottomLeftAndTopLeftRoundStyle);
            container.Add(RoundStyle.BottomRight | RoundStyle.TopLeft, AddBottomRightAndTopLeftRoundStyle);
            container.Add(RoundStyle.TopRight | RoundStyle.BottomLeft, AddTopRightAndBottomLeftRoundStyle);
    
            container.Add(RoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopLeft, AddBottomAndTopLeftRoundStyle);
            container.Add(RoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopRight, AddBottomAndTopRightRoundStyle);
            container.Add(RoundStyle.BottomLeft | RoundStyle.TopLeft | RoundStyle.TopRight, AddTopAndBottomLeftRoundStyle);
            container.Add(RoundStyle.BottomRight | RoundStyle.TopRight | RoundStyle.TopLeft, AddTopAndBottomRightRoundStyle);
    
            return container;
        }

三、GraphicsPath.AddArc方法

GraphicsPath.AddArc 方法如下:

public void AddArc(Rectangle rect, float startAngle, float sweepAngle);
public void AddArc(RectangleF rect, float startAngle, float sweepAngle);
public void AddArc(float x, float y, float width, float height, float startAngle, float sweepAngle);
public void AddArc(int x, int y, int width, int height, float startAngle, float sweepAngle);

此方法主要是繪制圓角的,繪制的方式與二位坐標的角度是不一樣,官方參數資料如下:

x                 矩形區域左上角的 X 軸坐標,這個矩形區域定義用來繪制弧形的橢圓形。

y                 矩形區域左上角的 Y 軸座標,這個矩形區域定義用來繪制弧形的橢圓形。

width           矩形區域的寬度,這個矩形區域定義用來繪制弧形的橢圓形。

height          矩形區域的高度,這個矩形區域定義用來繪制弧形的橢圓形。

startAngle    弧形的開始點角度,順時針自 X 軸所測得的度數。

sweepAngle  介於弧形的 startAngle 和結束點的角度。

如果圓形中具有先前的直線或曲線,會加入線段來將先前線段的結束點連接到弧形的開端。

弧形是沿著指定矩形范圍內的橢圓形周圍所描繪的。弧形的開始點是由橢圓形的 X 軸 (0 度角) 順時針測量開始點角度的度數所決定。結束點位置的決定很類似,從開始點順時針測量跨越角度的度數所決定。如果跨越的角度大於 360 度或小於 -360 度,則弧形分別跨越了 360 度或 -360 度。

弧形的開始點是由橢圓形的 X 軸 (0 度角) 順時針測量開始點角度的度數所決定,GraphicsPath增加對象的順序也是需要注意的(有部分連接線是系統繪制的)。此處與數學中二位坐標定義的角度是反方向的,需要特別注意。

四、繪制圓角組合

3.1 繪制一個圓角

矩行的一個圓角所有組合情況如下:RoundStyle.BottomLeft、RoundStyle.BottomRight、RoundStyle.TopLeft、RoundStyle.TopRight。繪制方法如下:

繪制一個圓角 
    
        private static void AddBottomLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLine(rect, path, radiusAdjustment);
            AddRightLine(rect, path, radiusAdjustment);
        }
    
        private static void AddBottomRightRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddLeftLine(rect, path, radiusAdjustment);
            AddTopLine(rect, path, radiusAdjustment);
        }
    
        private static void AddTopRightRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLine(rect, path, radiusAdjustment);
            AddLeftLine(rect, path, radiusAdjustment);
        }
    
        private static void AddTopLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddRightLine(rect, path, radiusAdjustment);
            AddBottomLine(rect, path, radiusAdjustment);
        }

效果圖如下:

3.2 繪制二個圓角

矩行的一個圓角所有組合情況如下:

RoundStyle.BottomRight | RoundStyle.BottomLeft

RoundStyle.BottomRight | RoundStyle.TopRight

RoundStyle.TopRight | RoundStyle.TopLeft

RoundStyle.BottomLeft | RoundStyle.TopLeft

RoundStyle.BottomRight | RoundStyle.TopLeft

RoundStyle.TopRight | RoundStyle.BottomLeft。

繪制方法如下:

繪制二個圓角 
    
        private static void AddTopRightAndBottomLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLineWithLeftOffset(path, rect, radius, radiusAdjustment, false);
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLineWithRightOffset(path, rect, radius, radiusAdjustment);
        }
    
        private static void AddBottomRightAndTopLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLineWithRightOffset(path, rect, radius, radiusAdjustment);
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLineWithLeftOffset(path, rect, radius, radiusAdjustment);
        }
    
        private static void AddBottomLeftAndTopLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddRightLine(rect, path, radiusAdjustment);
        }
    
        private static void AddTopRightAndTopLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLine(rect, path, radiusAdjustment);
        }
    
        private static void AddBottomRightAndTopRightRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddLeftLine(rect, path, radiusAdjustment);
        }
    
        private static void AddBottomRightAndBottomLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLine(rect, path, radiusAdjustment);
        }

效果圖如下:

3.2 繪制三個圓角

矩行的一個圓角所有組合情況如下:

RoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopLeft

RoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopRight

RoundStyle.BottomLeft | RoundStyle.TopLeft | RoundStyle.TopRight

RoundStyle.BottomRight | RoundStyle.TopRight | RoundStyle.TopLeft。

繪制方法如下:

繪制三個圓角 
    
        private static void AddTopAndBottomRightRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLineWithRightOffset(path, rect, radius, radiusAdjustment);
        }
    
        private static void AddTopAndBottomLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLineWithLeftOffset(path, rect, radius, radiusAdjustment, false);
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
        }
    
        private static void AddBottomAndTopRightRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLineWithRightOffset(path, rect, radius, radiusAdjustment);
            AddTopRightArc(rect, radius, path, radiusAdjustment);
        }
    
        private static void AddBottomAndTopLeftRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddTopLineWithLeftOffset(path, rect, radius, radiusAdjustment);
        }

效果圖如下:

3.4 繪制四個圓角

矩行的四個圓角所有組合情況如下:RoundStyle.All或者RoundStyle.BottomLeft | RoundStyle.BottomRight | RoundStyle.TopLeft | RoundStyle.TopRight。

繪制方法如下:

繪制四個圓角 
    
        private static void AddAllRoundStyle(GraphicsPath path,
            Rectangle rect, int radius, int radiusAdjustment)
        {
            AddTopLeftArc(rect, radius, path, radiusAdjustment);
            AddTopRightArc(rect, radius, path, radiusAdjustment);
            AddBottomRightArc(rect, radius, path, radiusAdjustment);
            AddBottomLeftArc(rect, radius, path, radiusAdjustment);

        }

效果圖如下:

四、總結

繪制圓角在美化控件方面的場景還是比較多的,本文采用枚舉的位操作來對所有情況進行操作。有一段時間沒寫隨筆了,可以寫的東西很多,由於個人的時間問題卻一直拖到現在。上面的圓角繪制例子是昨天作為練習寫的,只是簡單的手動測試了一下,如有BUG請及時通知本人,不勝感激。目前開發的產品很多控件都需要自繪,統計學需要寫的算法也比較多。雖然項目成員總人數為100,但開發所占的比例才40%不到,任重而道遠。

源碼下載: 矩陣圓角繪制源碼

http://files.cnblogs.com/jasenkin/Winform/Jasen.Framework.rar

作者:JasenKin

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

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