c# GDI+之Button重繪(轉)


在.NET平台混總是入門容易進階難。最近在看GDI+,重寫了一個自己的按鈕,感覺還不錯,值得推廣,(*^__^*) 嘻嘻……

寫了一個繪制圓角Button的工具類:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace WinformLx.Class
{
    enum buttonStyle
    {
        /// <summary>
        /// 正常為選中按鈕
        /// </summary>
        ButtonNormal,
        /// <summary>
        /// 獲得焦點的按鈕
        /// </summary>
        ButtonFocuse,
        /// <summary>
        /// 鼠標經過樣式
        /// </summary>
        ButtonMouseOver,
        /// <summary>
        /// 獲得焦點並鼠標經過
        /// </summary>
        ButtonFocuseAndMouseOver
    }
    /// <summary>
    /// 自定義GDI工具,繪制按鈕
    /// </summary>
    class Util_GDI
    {

        /// <summary>
        /// 繪制圓形按鈕(用法同矩形按鈕)
        /// </summary>
        /// <param name="text"></param>
        /// <param name="g"></param>
        /// <param name="Location"></param>
        /// <param name="r"></param>
        /// <param name="btnStyle"></param>
        public static void DrawCircleButton(string text, Graphics g, Point Location, int r, buttonStyle btnStyle)
        {
            Graphics Gcircle = g;
            Rectangle rect = new Rectangle(Location.X, Location.Y, r, r);
            Pen p = new Pen(new SolidBrush(Color.Black));
            Gcircle.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            Gcircle.DrawEllipse(p, rect);
            if (btnStyle == buttonStyle.ButtonFocuse)
            {
                Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#338FCC")), rect);
            }
            else if (btnStyle == buttonStyle.ButtonMouseOver)
            {
                Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#EAC100")), rect);
            }
            else if (btnStyle == buttonStyle.ButtonFocuseAndMouseOver)
            {
                Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#EAC100")), rect);
            }
           
            p.DashStyle = DashStyle.Dash;
            if (btnStyle != buttonStyle.ButtonNormal)
            {
               
                Gcircle.DrawEllipse(p, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));//虛線框
            }
            Gcircle.FillEllipse(new SolidBrush(Color.WhiteSmoke), new Rectangle(rect.X + 3, rect.Y + 3, rect.Width - 6, rect.Height - 6));
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            Gcircle.DrawString(text, new Font(new FontFamily("宋體"), 10), new SolidBrush(Color.Black), rect, sf);
            p.Dispose();
        }
        /// <summary> 
        /// 繪制圓角按鈕
        /// </summary> 
        /// <param name="Text">要繪制的文字</param>
        /// <param name="g">Graphics 對象</param> 
        /// <param name="rect">要填充的矩形</param> 
        /// <param name="btnStyle"></param>
        public static void DrawRoundButton(string Text, Graphics g, Rectangle rect,buttonStyle btnStyle)
        {
            //g.Clear(Color.White);
            g.SmoothingMode = SmoothingMode.AntiAlias;//消除鋸齒
            Rectangle rectangle = rect;
            Brush b = b = new SolidBrush(Color.Black);
            if (btnStyle == buttonStyle.ButtonFocuse)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#338FCC"));
            }
            else if (btnStyle == buttonStyle.ButtonMouseOver)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
            }
            else if (btnStyle == buttonStyle.ButtonFocuseAndMouseOver)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
            }
            g.DrawPath(new Pen(b),GetRoundRectangle(rectangle, 2));
            rectangle = new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4);
            Pen p=new Pen(Color.Black,0.5f);
            p.DashStyle = DashStyle.Dash;
            if (btnStyle == buttonStyle.ButtonFocuse || btnStyle == buttonStyle.ButtonFocuseAndMouseOver)
            {
                g.DrawRectangle(p,rectangle);//虛線框
            }
            g.FillRectangle(new SolidBrush(Color.WhiteSmoke),rectangle);//白色背景
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            g.DrawString(Text, new Font("宋體", 10), new SolidBrush(Color.Black), rectangle, sf);
            p.Dispose();
            b.Dispose();
            g.SmoothingMode = SmoothingMode.Default;
        }
 
       /// <summary> 
        /// 根據普通矩形得到圓角矩形的路徑 
        /// </summary> 
        /// <param name="rectangle">原始矩形</param> 
        /// <param name="r">半徑</param> 
        /// <returns>圖形路徑</returns> 
        private static GraphicsPath GetRoundRectangle(Rectangle rectangle, int r)
        {
            int l = 2 * r;
            // 把圓角矩形分成八段直線、弧的組合,依次加到路徑中 
            GraphicsPath gp = new GraphicsPath();
            gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
            gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);

            gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
            gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);

            gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
            gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);

            gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
            gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
            return gp;
        }

    }
}
新建一個cs命名為MyButton,繼承Button類,重寫Button類的Paint方法:

using System;
using System.Windows;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using WinformLx.Class; //引用之前工具類的命名空間

namespace WinformLx.UserControls
{
    public class MyButton : System.Windows.Forms.Button
    {
        private bool mouseover = false;//鼠標經過
        public MyButton()
        {
            this.Cursor = System.Windows.Forms.Cursors.Hand;
        }

        protected override void OnPaint(PaintEventArgs e)
        {

            //在這里用自己的方法來繪制Button的外觀(其實也就是幾個框框)
            Graphics g = e.Graphics;
            g.Clear(this.BackColor);
            Rectangle rect = e.ClipRectangle;
            rect = new Rectangle(rect.X,rect.Y,rect.Width-1,rect.Height-2);
            //g.ReleaseHdc();
            if (mouseover)
            {
                if (Focused)
                {
                    Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonFocuseAndMouseOver);
                    return;
                }
                Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonMouseOver);
                return;
            }
            if (Focused)
            {
                Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonFocuse);
                return;
            }
            Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonNormal);
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            mouseover = true;
            base.OnMouseEnter(e);
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            mouseover = false;
            base.OnMouseLeave(e);   
        }
    }
}
上面的工作完成以后會在vs的工具欄發現剛剛自己寫的那個MyButton


新建一個窗口,拖上去就可以了。

和windows繪制的button明顯不一樣吧,因為只是重寫了繪制方法,改變了一下外觀,事件那些還是一樣可以用的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM