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;

  }

  }

  }

  }