CSkin博客

标题: 【Button美化】五分钟带你入门GDI+重绘组件 [打印本页]

作者: 乔克斯    时间: 2014-7-21 11:58
标题: 【Button美化】五分钟带你入门GDI+重绘组件
在这之前 首先的准备好素材导入到工程资源里面去:



素材提取参考:点击跳转相关帖、此帖有教你如何取得素材,便于自己二次开发。
其次 这些图完全可以做成一张图 然后绘制的时候 自己从大图上面切图绘制就行、、不然到时候 会有很多图看着别扭、、
但分开也有分开的好处,更可定义性强,素材更容易找。

[C#] 纯文本查看 复制代码
public partial class ButtonEx : Button
{
    public ButtonEx() {
        //首先开启双缓冲,防止闪烁
        //双缓冲的一大堆设置 具体参数含义参照msdn的ControlStyles枚举值
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.ResizeRedraw, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        this.BackColor = Color.Transparent;
    }
    //用来标示是否鼠标正在悬浮在按钮上  true:悬浮在按钮上 false:鼠标离开了按钮
    private bool m_bMouseHover;
    //用来标示是否鼠标点击了按钮  true:按下了按钮 false:松开了按钮
    private bool m_bMouseDown;

    //重载鼠标悬浮的事件
    protected override void OnMouseEnter(EventArgs e) {
        //当鼠标进入控件时,标示变量为进入了控件
        m_bMouseHover = true;
        //刷新面板触发OnPaint重绘
        this.Invalidate();
        base.OnMouseEnter(e);
    }

    //重载鼠标离开的事件
    protected override void OnMouseLeave(EventArgs e) {
        //当鼠标离开控件时,标示变量为离开了控件
        m_bMouseHover = false;
        //刷新面板触发OnPaint重绘
        this.Invalidate();
        base.OnMouseLeave(e);
    }

    //重载鼠标按下的事件
    protected override void OnMouseDown(MouseEventArgs mevent) {
        //当鼠标按下控件时,标示变量为按下了控件
        m_bMouseDown = true;
        //刷新面板触发OnPaint重绘
        this.Invalidate();
        base.OnMouseDown(mevent);
    }

    //重载鼠标松开的事件
    protected override void OnMouseUp(MouseEventArgs mevent) {
        //当鼠标松开时,标示变量为按下并松开了控件
        m_bMouseDown = false;
        //刷新面板触发OnPaint重绘
        this.Invalidate();
        base.OnMouseUp(mevent);
    }

    //重载绘画事件
    protected override void OnPaint(PaintEventArgs pevent) {
        base.OnPaint(pevent);
        //因为上面调用了base会绘制原生控件 重刷一下背景清掉原生绘制 不然自己绘制的是重叠在原生绘制上
        base.OnPaintBackground(pevent);
        //得到绘画句柄
        Graphics g = pevent.Graphics;
        //定义字体格式
        StringFormat sf = new StringFormat();
        sf.Alignment = StringAlignment.Center;
        sf.LineAlignment = StringAlignment.Center;
        //处理热键 当Alt点下时
        sf.HotkeyPrefix = this.ShowKeyboardCues ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
        //判断使用什么资源图
        Bitmap bmpDraw = Properties.Resources.QBtn_Normal;
        //如果禁用了,则使用禁用时的样式图片绘制,否则调用其他满足条件的样式图片绘制
        if (!this.Enabled) bmpDraw = Properties.Resources.Qbtn_Gray;
        else if (m_bMouseDown) bmpDraw = Properties.Resources.QBtn_Down;
        else if (m_bMouseHover) bmpDraw = Properties.Resources.QBtn_High;
        else if (this.Focused) bmpDraw = Properties.Resources.QBtn_Focus;
        //绘制背景(若不知道这句啥意思 参照九宫切图里面的代码)
        RenderHelper.RenderBackground(g, bmpDraw, this.ClientRectangle);
        //如果禁用了
        if (!this.Enabled) {
            //则绘制双重阴影文字
            g.DrawString(this.Text, this.Font, Brushes.White, this.ClientRectangle, sf);
            g.TranslateTransform(-1, -1);//左上移动一个单位坐标系
            g.DrawString(this.Text, this.Font, Brushes.DarkGray, this.ClientRectangle, sf);
            g.ResetTransform();
            return;
        }
        //否则,默认绘制正常字体
        using (SolidBrush sb = new SolidBrush(this.ForeColor)) {
            g.DrawString(this.Text, this.Font, sb, this.ClientRectangle, sf);
        }
    }
}


这样就大功告成了,上面几十行代码就搞定了、是不是很简单呢、下图是运行效果

分别是 正常状态的按钮 鼠标移动上去 获得焦点 禁用

作者: 原始    时间: 2014-7-21 12:04
抢个沙发!楼主能不能不用重绘,向微软那样直接绘出来?:lol
作者: 乔克斯    时间: 2014-7-21 12:06
原始 发表于 2014-7-21 12:04
抢个沙发!楼主能不能不用重绘,向微软那样直接绘出来?

不用重绘- -。。控件很多原生的功能啊,事件响应就没有了。
作者: 乔克斯    时间: 2014-7-21 12:31
原始 发表于 2014-7-21 12:04
抢个沙发!楼主能不能不用重绘,向微软那样直接绘出来?

继承Control,再进行绘制,就是你所说的,重头画起和定义事件功能。
作者: iHomeSoft    时间: 2014-7-27 15:41
那里有最新dll下载的啊
作者: 乔克斯    时间: 2014-7-27 15:44
iHomeSoft 发表于 2014-7-27 15:41
那里有最新dll下载的啊

新版DLL还没上传贴,耐心等候
作者: 乔克斯    时间: 2014-7-27 16:12
iHomeSoft 发表于 2014-7-27 15:41
那里有最新dll下载的啊

【Metro风格】Metro窗体DEMO-14.7.2版本
http://bbs.cskin.net/forum.php?m ... id=84&fromuid=2
(出处: CSkin论坛)

作者: 王龙    时间: 2014-10-6 13:53
留名,日后细看
作者: Monn    时间: 2014-10-9 11:55
注释很详细,多谢楼主!
作者: HJL    时间: 2014-10-9 17:07
又是干货呀!
作者: slljlzw    时间: 2015-1-13 11:28
谢谢楼主的无私分享
作者: 埃菲尔    时间: 2015-1-13 15:12
感谢 分享 太赞了
作者: mumupudding    时间: 2015-1-14 09:42
感谢 分享
作者: FlamHaze    时间: 2017-3-27 16:58
留名。。。。。。。。
作者: ksig    时间: 2017-10-7 15:14
问题是RenderHelper在哪里定义的?
作者: liao2930161655    时间: 2017-11-6 23:26
楼主  有了素材 还有上面方该具体怎么做呢
作者: liao2930161655    时间: 2017-11-6 23:27
楼主有了素材 和上面的教程 具体是怎么做的呢比如怎么导入工程资源
作者: fabyerse123    时间: 2017-12-14 16:49
占个位````````
作者: a1030700831    时间: 2018-1-8 15:45
我想问一下如果按钮放大缩小怎么办呢。。
作者: bozi0822    时间: 2019-11-5 09:28
很给力的贴
作者: 德玛西亚青铜    时间: 2020-2-15 19:27
66666666666666666666




欢迎光临 CSkin博客 (http://bbs.cskin.net/) Powered by Discuz! X3.2