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明显不一样吧,因为只是重写了绘制方法,改变了一下外观,事件那些还是一样可以用的。

原文地址:https://www.cnblogs.com/zzh1236/p/3044686.html