C# 使用PictureBox实现图片按钮控件的示例步骤
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Drawing.Imaging;
namespace PicBtn
{
public partial class RoundPictureBox : PictureBox
{
[Category("派生属性"), Description("有的图标是正圆形,因此此处设置控件的长宽是否相等")]
public bool IsWeightWidthEqual { get; set; }
// 该属性尚未使用
[Category("派生属性"), Description("表明是否由多个图片来表示图片框的按钮特效")]
public bool IsMultiImage { get; set; }
// 分割后图片容器
List SplitedImage = null;
Image buffImg;
Graphics buffImgG;
public RoundPictureBox()
{
InitializeComponent();
//双缓冲区绘制
DoubleBuffered = true;
SizeMode = PictureBoxSizeMode.Normal;
// 图片素材路径,视具体情况而定(可以更改)
this.ImageLocation = @"D:文档VS项目PicButtonview_next.png";
//按钮图片分割
this.Image = Image.FromFile(ImageLocation);
// 图片宽度(Width)164,将其分为4段并放到容器中
SplitedImage = ImageSplit(164, 4);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
// 创建空图形
buffImg = new Bitmap(Width,Height);
// 根据空图形创建画布Graphics对象
buffImgG = Graphics.FromImage(buffImg);
// 用画布对象,以背景色刷新空图形
buffImgG.Clear(this.BackColor);
//双三次插值
pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
//抗锯齿
pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//图形轨迹
GraphicsPath gp = new GraphicsPath();
//限定圆形绘制长方形区域
//限定为正方形
Rectangle limitedRec = new Rectangle();
Point startDrawingPoint = new Point(0, 0);
limitedRec.Location = startDrawingPoint;
limitedRec.Size = new Size(Width - 1, Height - 1);
if (IsWeightWidthEqual)
{
int fixedWidth = Width - 1;
Height = Width;
Width = Height;
limitedRec.Size = new Size(fixedWidth, fixedWidth);
}
//以下代码是为了把图片框的显示边界改成圆形
//添加轨迹为椭圆
gp.AddEllipse(limitedRec);
//重新设置边界
Region rg = new Region(gp);
this.Region = rg;
//销毁资源
rg.Dispose();
gp.Dispose();
}
//绘制鼠标进入点击并离开的图像
/*
* 完整的点击过程如下(只考虑鼠标左键的情况)
* 1. 鼠标指针进入PictureBox(以下简称“该控件”),触发事件 MouseEnter
* 2. 鼠标按下不动的一瞬间,触发事件 MouseDown
* 3. 鼠标松开一瞬间,触发事件 MouseUp
* 4. 鼠标指针离开该控件,触发事件 MouseLeave
*/
//1.鼠标进入
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
using (Graphics g = Graphics.FromHwnd(this.Handle))
{
// 双三次插值
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// 抗锯齿
g.SmoothingMode = SmoothingMode.AntiAlias;
// 再次以背景色刷新空白图形
buffImgG.Clear(this.BackColor);
// 在空白图形上绘制分割后的第2个小图片
buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
// 依据上述空白图形buffImgG创建缓冲Graphics,指定区域为该控件工作区
BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
// BufferedGraphics绘制整个图形,指定绘制区域为该控件工作区
// 此处推荐使用DrawImageUnscaledAndClipped
buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
// 图形缓冲区写入到当前控件Graphics对象
buff.Render(g);
}
}
//2.鼠标按下
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
using (Graphics g = Graphics.FromHwnd(this.Handle))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
buffImgG.InterpolationMode = InterpolationMode.HighQualityBicubic;
buffImgG.SmoothingMode = SmoothingMode.HighQuality;
buffImgG.Clear(BackColor);
buffImgG.DrawImageUnscaledAndClipped(SplitedImage[2],ClientRectangle);
BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
buff.Render(g);
}
}
//3. 鼠标按键松开
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
using (Graphics g = Graphics.FromHwnd(this.Handle))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
buffImgG.Clear(BackColor);
buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
buff.Render(g);
}
}
//4.鼠标离开
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
using (Graphics g = Graphics.FromHwnd(this.Handle))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
buffImgG.Clear(BackColor);
buffImgG.DrawImageUnscaledAndClipped(SplitedImage[3], ClientRectangle);
BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
buff.Render(g);
}
}
///
/// 图片分割函数,此处仅仅按图片宽度来分割
///
/// 图片素材宽度
/// 要分割为几段,默认是1段
/// 分割后的图片集合
private List ImageSplit(int ImageWidth, int SegmentsNum = 1)
{
// 定义分割后的图片存放容器
List SplitedImage = new List();
// 克隆按钮背景图片
Bitmap SrcBmp = new Bitmap(this.Image);
// 指定图片像素格式为ARGB型
PixelFormat ReslouteFormat = PixelFormat.Format32bppArgb;
// 指定分割区域
Rectangle SplitAreaRec = new Rectangle();
// 如果图片尺寸为负值
if (ImageWidth <= 0 || SegmentsNum <= 0)
return SplitedImage;
else
{
// 依据要分割的段数来做循环
// 从 0(含) 到 SegmentsNum - 1(含)
for (int i = 0; i < SegmentsNum; i++)
{
/*
* 在这里要把图片分割为4段小图片,每一段图片大小均为41 * 41
* 以下列举出每个小图片的左上角坐标(即起始坐标)
* (0, 0)
* (41, 0)
* (82, 0)
* (123, 0)
* Y 坐标均为 0
*
* 计算每个小图片的宽度:ImageWidth / SegmentsNum (总宽度/要分割的段数)
* 因此 X = i * (ImageWidth / SegmentsNum)
*/
SplitAreaRec.X = 0 + i * (ImageWidth / SegmentsNum);
SplitAreaRec.Y = 0;
// 小图片为正方形,所以以下这两个值一样
SplitAreaRec.Width = ImageWidth / SegmentsNum;
SplitAreaRec.Height = ImageWidth / SegmentsNum;
// 以指定的像素格式,克隆分割的图像
Bitmap SplitedBmp = SrcBmp.Clone(SplitAreaRec, ReslouteFormat);
// 添加进集合
SplitedImage.Add(SplitedBmp);
}
GC.Collect();
return SplitedImage;
}
}
}
}
- .NET Core系列之MemoryCache 初识
- 007手机一键Root(安机网一键Root) v3.0 官方最新版 一键ROOT您的Android手机
- 12306密码被盗了怎么办?12306密码外泄解决方法
- 12个字的qq网名
- 150M迷你型无线路由器怎么设置?
- 192.168.1.1打不开怎么办?路由器192.168.1.1打不开的原因以及解决办法
- 2011年电子报合订本 电子报 编辑部 中文 PDF版 [84M]
- 2015年1月15日小米新旗舰发布会现场图文直播
- 2016.3.1vivo Xplay5新品发布会现场视频直播 优酷直播
- 2016华为P9发布会视频直播地址 4月15日华为P9国行发布会直播