热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[转]C#winForm创建水晶风格的按钮

时下水晶风格比较流行,在天极网看到一篇制作水晶按钮控件的文章,首先启动VisualStudio2005,新建空白解决方案,我们取名为:TestCrystalButton,然后在项目
时下水晶风格比较流行,在天极网看到一篇制作水晶按钮控件的文章,
首先启动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的引用即可制作出漂亮的水晶控件啦!

推荐阅读
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了一种解析GRE报文长度的方法,通过分析GRE报文头中的标志位来计算报文长度。具体实现步骤包括获取GRE报文头指针、提取标志位、计算报文长度等。该方法可以帮助用户准确地获取GRE报文的长度信息。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了Foundation框架中一些常用的结构体和类,包括表示范围作用的NSRange结构体的创建方式,处理几何图形的数据类型NSPoint和NSSize,以及由点和大小复合而成的矩形数据类型NSRect。同时还介绍了创建这些数据类型的方法,以及字符串类NSString的使用方法。 ... [详细]
  • 颜色迁移(reinhard VS welsh)
    不要谈什么天分,运气,你需要的是一个截稿日,以及一个不交稿就能打爆你狗头的人,然后你就会被自己的才华吓到。------ ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有