C# winForm 建立水晶風格的按鈕

iDotNetSpace發表於2008-09-28
時下水晶風格比較流行,在天極網看到一篇製作水晶按鈕控制元件的文章,
首先啟動Visual Studio 2005,新建空白解決方案,我們取名為:TestCrystalButton,
然後在專案導航欄上右擊滑鼠新增新專案,為此解決方案新增新的C# Windows 控制元件庫,取名為MyControls。
IDE會建立一個繼承於UserControl名為UserControl1的類,修改程式碼使其繼承自Button,
並將原檔案中所有引用UserControl1名稱的地方都更改為CrystalButton,在專案導航欄中把UserControl1.cs更名為CrystalButton.cs
 然後將InitializeComponent()方法中的
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
語句註釋掉,因為從Button控制元件不可能有自動縮放功能,它必須依賴於其父控制元件。
在原始檔頭部新增對System.Drawing.Imaging和System.Drawing.Drawing2D程式集的引用。
首先需要建立一個列舉型別MouseActionType,當按鈕需要繪製時會根據當前滑鼠的位置進行不同狀態的繪製,
程式碼如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace TestCrystalButton
{
    public partial class CrystalButton : Button
    {
        public CrystalButton()
        {
            InitializeComponent();
        }

        private enum MouseActionType
        {
            None,
            Hover,
            Click
        }
        private MouseActionType mouseAction;

        private GraphicsPath GetGraphicsPath(Rectangle rc, int r)
        {
            int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
            GraphicsPath path = new GraphicsPath();
            path.AddArc(x, y, r, r, 180, 90);
            //Upper left corner
            path.AddArc(x + w - r, y, r, r, 270, 90);
            //Upper right cornr
            path.AddArc(x + w - r, y + h - r, r, r, 0, 90);
            //Lower right corner
            path.AddArc(x, y + h - r, r, r, 90, 90);
            //Lower left corner
            path.CloseFigure();
            return path;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.Clear(SystemColors.ButtonFace);
            Color clr = Color.Wheat;//BtnColor;
            int shadowOffset = 8;
            int btnOffset = 0;
            switch(mouseAction)
            {
                case MouseActionType.Click :
                    shadowOffset = 4;
                    clr = Color.LightGray;
                    btnOffset = 2;
                    break;
                case MouseActionType.Hover:
                    clr = Color.LightGray;
                    break;                   
            }
            g.SmoothingMode = SmoothingMode.AntiAlias;
            // 建立按鈕本身的圖形           
            Rectangle rc = new Rectangle(btnOffset, btnOffset, this.ClientSize.Width - 8 - btnOffset, this.ClientSize.Height - 8 - btnOffset);
            GraphicsPath path1 = this.GetGraphicsPath(rc, 20);
            LinearGradientBrush br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rc.Height + 6), clr, Color.White);
            // 建立按鈕陰影
            Rectangle rc2 = rc;
            rc2.Offset(shadowOffset, shadowOffset);
            GraphicsPath path2 = this.GetGraphicsPath(rc2, 20);
            PathGradientBrush br2 = new PathGradientBrush(path2);
            br2.CenterColor = Color.Black;
            br2.SurroundColors = new Color[] { SystemColors.ButtonFace };
            //為了更逼真,我們將漸變結束顏色設定為窗體前景顏色,可以根據視窗的前景顏色適當調整
            //建立按鈕頂部白色漸變
            Rectangle rc3 = rc;
            rc3.Inflate(-5, -5);
            rc3.Height = 15;
            GraphicsPath path3 = GetGraphicsPath(rc3, 20);
            LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical);
            // 繪製圖形
            g.FillPath(br2, path2); //繪製陰影
            g.FillPath(br1, path1); //繪製按鈕
            g.FillPath(br3, path3); //繪製頂部白色泡泡
            //設定記憶體點陣圖物件,進行二級快取繪圖操作
            Rectangle buttonBitmapRectangle = new Rectangle(rc.Location, rc.Size);
            Bitmap buttonBitmap = new Bitmap(buttonBitmapRectangle.Width, buttonBitmapRectangle.Height);
            Graphics g_bmp = Graphics.FromImage(buttonBitmap);
            g_bmp.SmoothingMode = SmoothingMode.AntiAlias;
            g_bmp.FillPath(br1, path1);
            g_bmp.FillPath(br3, path3);
            //將region賦值給button
            Region rgn = new Region(path1);
            rgn.Union(path2);
            this.Region = rgn;
            // 繪製按鈕的文字
            GraphicsPath path4 = new GraphicsPath();
            RectangleF path1bounds = path1.GetBounds();
            Rectangle rcText = new Rectangle((int)path1bounds.X + btnOffset, (int)path1bounds.Y + btnOffset, (int)path1bounds.Width, (int)path1bounds.Height);
            StringFormat strformat = new StringFormat();
            strformat.Alignment = StringAlignment.Center;
            strformat.LineAlignment = StringAlignment.Center;
            path4.AddString(this.Text, this.Font.FontFamily, (int)this.Font.Style, this.Font.Size, rcText, strformat);
            Pen txtPen = new Pen(this.ForeColor, 1);
            g.DrawPath(txtPen, path4);
            g_bmp.DrawPath(txtPen, path4);
        }
 
    }
}

在Windows Application中新增對此dll的引用即可製作出漂亮的水晶控制元件啦!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-466020/,如需轉載,請註明出處,否則將追究法律責任。

相關文章