分享

C#水晶ButtonWinForm自定义控件

 Cloud书屋 2012-11-21

首先启动Visual Studio 2008,新建windows 窗体控件库,取名为:G_Button。
        
       IDE会创建一个继承于UserControl名为UserControl1的类,把它删除,再新建自定义控件。
        
        修改代码使其继承自Button,
        
        再添加命名空间: using System.Drawing.Drawing2D;
using System.Drawing.Imaging;         然后在该类定义一个枚举MouseActionType,为鼠标动作类型。此枚举中有三个值分别是:None,HoverClick,意思为无,鼠标悬停和鼠标点击。然后定义四个全局变量,这些都是水晶按钮必备的要素:
private enum MouseActionType
{
    None,
    Hover,
    Click
}
private MouseActionType mouseactiontype;//定义鼠标动作类型
private ImageAttributes imgattr = new ImageAttributes();//实例化一个图像属性类
private Bitmap btnbmp;//定义一个位图
private Rectangle btnrc;//定义一个矩形         现在来编写自定义控件的构造函数,在构造函数里初始化按钮开始的样子。 public GZX_Button()
{
    InitializeComponent();//该自定义控件的初始化组件的方法(系统自动生成)
    mouseactiontype = MouseActionType.None;
     this.SetStyle(ControlStyles.AllPaintingInWmPaint |//禁止擦除背景
    ControlStyles.DoubleBuffer |//双缓冲
    ControlStyles.UserPaint, true);
    //下面这些可以不设置,也可以自己定义
    this.Font = new Font("Arial Black", 12, FontStyle.Bold);//设置字体
    this.BackColor = Color.DarkTurquoise;//设计背景颜色
    this.Size = new Size(112, 48);//设置大小
}         好了大体差不多了,下来具体的了,水晶图形: /// <summary>
/// 按钮形状
/// </summary>
/// <param name="rc">按钮的坐标和大小</param>
/// <param name="r">按钮圆弧的半径</param>
/// <returns>按钮形状</returns>
private GraphicsPath GetGraphicsPath(Rectangle rc, int r)
{
     int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
     GraphicsPath gpath = new GraphicsPath();
    gpath.AddArc(x, y, r, r, 180, 90);//左上角圆弧
    gpath.AddArc(x + w - r, y, r, r, 270, 90);//右上角圆弧
    gpath.AddArc(x + w - r, y + h - r, r, r, 0, 90);//右下角圆弧
    gpath.AddArc(x, y + h - r, r, r, 90, 90);//左下角圆弧
    gpath.CloseFigure();//闭合
    return gpath;
}         下来重写OnPaint()方法,此方法用来画自己按钮本身:
      

protected override void OnPaint(PaintEventArgs pe)
{
    //base.OnPaint(pe);
    Graphics g = pe.Graphics;//创建该控件的画布
    g.Clear(SystemColors.ButtonFace);//重置背景颜色,可以自定义
    Color clr = this.BackColor;
    int shadowOff = 2;//阴影边距
    int btnOff = 0;//按钮边距
    switch (mouseactiontype)//根据mouseactiontype变量进行不同状态的绘制。
    {
        case MouseActionType.None:
            break;
        case MouseActionType.Hover:
            clr = Color.LightGray;
            break;
         case MouseActionType.Click:
             shadowOff = 4;
             clr = Color.LightGray;
             btnOff = 2;
             break;
        default:
            break;
    }
    g.SmoothingMode = SmoothingMode.AntiAlias;//消除锯齿
    //创建按钮本身的图形
    Rectangle rc1 = new Rectangle(btnOff, btnOff, this.ClientSize.Width - 8 - btnOff, this.ClientSize.Height - 8 - btnOff);
    GraphicsPath gpath1 = this.GetGraphicsPath(rc1, 20);
    LinearGradientBrush br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rc1.Height + 6), clr, Color.White);
     //创建按钮阴影
    Rectangle rc2 = rc1;
    rc2.Offset(shadowOff, shadowOff);
    GraphicsPath gpath2 = this.GetGraphicsPath(rc2, 20);
    PathGradientBrush br2 = new PathGradientBrush(gpath2);
    br2.CenterColor = Color.Black;
    br2.SurroundColors = new Color[] { SystemColors.ButtonFace };
    //为了更逼真,我们将渐变结束颜色设定为窗体前景颜色,可以根据窗口的前景颜色适当调整
    //创建按钮顶部白色渐变
    Rectangle rc3 = rc1;
     rc3.Inflate(-5, -5);
    rc3.Height = 15;
    GraphicsPath gpath3 = GetGraphicsPath(rc3, 20);
    LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical);
    // 绘制图形
    g.FillPath(br2, gpath2); //绘制阴影
    g.FillPath(br1, gpath1); //绘制按钮
    g.FillPath(br3, gpath3); //绘制顶部白色泡泡
    //设定内存位图对象,进行二级缓存绘图操作
    btnrc = new Rectangle(rc1.Location, rc1.Size);
    btnbmp = new Bitmap(btnrc.Width, btnrc.Height);
    Graphics g_bmp = Graphics.FromImage(btnbmp);
    g_bmp.SmoothingMode = SmoothingMode.AntiAlias;
    g_bmp.FillPath(br1, gpath1);
    g_bmp.FillPath(br3, gpath3);
    //将region赋值给button
    Region rgn = new Region(gpath1);
    rgn.Union(gpath2);
    this.Region = rgn;
    // 绘制按钮的文本
    GraphicsPath gpath4 = new GraphicsPath();
    RectangleF gpath1bounds = gpath1.GetBounds();
    Rectangle rcText = new Rectangle((int)gpath1bounds.X + btnOff, (int)gpath1bounds.Y + btnOff, (int)gpath1bounds.Width, (int)gpath1bounds.Height);
    StringFormat strformat = new StringFormat();
    strformat.Alignment = StringAlignment.Center;
    strformat.LineAlignment = StringAlignment.Center;
    gpath4.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, gpath4);
    g_bmp.DrawPath(txtPen, gpath4);
}

        控件会捕获OnMouseDownOnMouseUpOnMouseHoverOnMouseEnterOnMouseLeave事件并将mouseactiontype变量设置为不同的枚举值,以便在OnPaint事件发生时根据mouseactiontype变量进行不同状态的绘制。

protected override void OnMouseDown(MouseEventArgs mevent)//鼠标按下事件
{
    if (mevent.Button == MouseButtons.Left)
    {
        this.mouseactiontype = MouseActionType.Click;
        this.Invalidate();
    }
    base.OnMouseDown(mevent);
}

protected override void OnMouseUp(MouseEventArgs mevent)//鼠标弹起事件
{
    this.mouseactiontype = MouseActionType.Hover;
    this.Invalidate();
    base.OnMouseUp(mevent);
}

protected override void OnMouseHover(EventArgs e)//鼠标悬停事件
{
    this.mouseactiontype = MouseActionType.Hover;
    this.Invalidate();
    base.OnMouseHover(e);
}

protected override void OnMouseEnter(EventArgs e)//鼠标进入事件
{
    this.mouseactiontype = MouseActionType.Hover;
    this.Invalidate();
    base.OnMouseEnter(e);
}

protected override void OnMouseLeave(EventArgs e)//鼠标离开事件
{
    this.mouseactiontype = MouseActionType.None;
    this.Invalidate();
    base.OnMouseLeave(e);
}

        该示例控件和程序在Visual Studio 2008 RTMWindows XP SP3下编译运行通过。
        作品下载:http://down./space/file/gzxchaoren/-4e0a-4f20-5206-4eab/G_Button.rar/.page

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多