引言

  我们有时候会在程序的文件夹里看见一些图标,而这些图标恰好是作为按钮的背景图片来使用的。鼠标指针在处于不同状态时,有“进入按钮”、“按下左键”,“松开”,“离开按钮”,则按钮的背景图片也在发生改变。这些图片大致如下(来自爱奇艺万能播放器PC端): 

  全文第一张图片素材为例,这张图片可以分为4段(下图所示),恰好表示鼠标指针在操作控件时各个不同的状态,从左到右依次表示为“初始状态”(默认显示的背景)、“指针进入按钮区域或鼠标左键松开”,“鼠标左键按下不动”,“鼠标指针离开按钮区域”

  本身这个图片素材设计的就很巧妙,它的尺寸是164 * 41,因此每一段的尺寸刚好是41 * 41

  在贴代码之前请先看看效果:

编译环境及说明

  • Microsoft Visual Studio 2010
  • C# .Net Framework 4.0
  • 除了实现这个图片按钮的功能,还添加了一些代码来减少甚至防止图片按钮在与鼠标指针交互时的闪烁

图片素材分割

  显然上述的图片素材需要分割为4段作为鼠标指针的不同状态,实现分割的思路为

    • 把图片转换为Image对象
    • 克隆该Image对象(防止直接操作控件背景导致问题)
    • 创建元素类型为Bitmap的容器List,用于存放分割后的4个图片对象
    • 定义矩形区域Rectangle结构体,它用来表明应该取整个图片素材中的哪个部分,用for循环逐个计算出这4段图片的左上角坐标(即起始坐标)、宽度、高度,再将值对应的赋予Rectangle结构体中的属性
    • 克隆上一步Rectangle结构体所对应区域下的图片块,并添加到第3步中提到的List容器中并返回该容器

  由此可以定义一个函数 ImageSplit ,代码如下

  1. 1 /// <summary>
  2. 2 /// 图片分割函数,此处仅仅按图片宽度来分割
  3. 3 /// </summary>
  4. 4 /// <param name="ImageWidth">图片素材宽度</param>
  5. 5 /// <param name="SegmentsNum">要分割为几段,默认是1段</param>
  6. 6 /// <returns>分割后的图片集合</returns>
  7. 7 private List<Bitmap> ImageSplit(int ImageWidth, int SegmentsNum = 1)
  8. 8 {
  9. 9 // 定义分割后的图片存放容器
  10. 10 List<Bitmap> SplitedImage = new List<Bitmap>();
  11. 11 // 克隆按钮背景图片
  12. 12 Bitmap SrcBmp = new Bitmap(this.Image);
  13. 13 // 指定图片像素格式为ARGB型
  14. 14 PixelFormat ReslouteFormat = PixelFormat.Format32bppArgb;
  15. 15 // 指定分割区域
  16. 16 Rectangle SplitAreaRec = new Rectangle();
  17. 17 // 如果图片尺寸为负值
  18. 18 if (ImageWidth <= 0 || SegmentsNum <= 0)
  19. 19 return SplitedImage;
  20. 20 else
  21. 21 {
  22. 22 // 依据要分割的段数来做循环
  23. 23 // 从 0(含) 到 SegmentsNum - 1(含)
  24. 24 for (int i = 0; i < SegmentsNum; i++)
  25. 25 {
  26. 26 /*
  27. 27 * 在这里要把图片分割为4段小图片,每一段图片大小均为41 * 41
  28. 28 * 以下列举出每个小图片的左上角坐标(即起始坐标)
  29. 29 * (0, 0)
  30. 30 * (41, 0)
  31. 31 * (82, 0)
  32. 32 * (123, 0)
  33. 33 * Y 坐标均为 0
  34. 34 *
  35. 35 * 计算每个小图片的宽度:ImageWidth / SegmentsNum (总宽度/要分割的段数)
  36. 36 * 因此 X = i * (ImageWidth / SegmentsNum)
  37. 37 */
  38. 38 SplitAreaRec.X = 0 + i * (ImageWidth / SegmentsNum);
  39. 39 SplitAreaRec.Y = 0;
  40. 40 // 小图片为正方形,所以以下这两个值一样
  41. 41 SplitAreaRec.Width = ImageWidth / SegmentsNum;
  42. 42 SplitAreaRec.Height = ImageWidth / SegmentsNum;
  43. 43 // 以指定的像素格式,克隆分割的图像
  44. 44 Bitmap SplitedBmp = SrcBmp.Clone(SplitAreaRec, ReslouteFormat);
  45. 45 // 添加进集合
  46. 46 SplitedImage.Add(SplitedBmp);
  47. 47 }
  48. 48 GC.Collect();
  49. 49 return SplitedImage;
  50. 50 }
  51. 51 }

事件处理

  该图片按钮控件有几个事件需要处理,包括:

    • OnPaint(控件绘制事件)
    • OnMouseEnter(鼠标指针进入控件区域触发事件)
    • OnMouseDown (鼠标左键按下)
    • OnMouseUp  (鼠标左键松开)
    • OnMouseLeave(鼠标指针离开控件区域)

OnPaint事件

  首先在自定义控件类中定义私有对象,缓冲 Image 对象(最开始为空白图形)和对应的缓冲 Graphics 对象(在空白图形上绘制图案),这是为了减少闪烁

  1. Image buffImg;
  2. Graphics buffImgG;

  具体代码如下:

  1. 1 protected override void OnPaint(PaintEventArgs pe)
  2. 2 {
  3. 3 base.OnPaint(pe);
  4. 4 // 创建空图形
  5. 5 buffImg = new Bitmap(Width,Height);
  6. 6 // 根据空图形创建画布Graphics对象
  7. 7 buffImgG = Graphics.FromImage(buffImg);
  8. 8 // 用画布对象,以背景色刷新空图形
  9. 9 buffImgG.Clear(this.BackColor);
  10. 10
  11. 11 //双三次插值
  12. 12 pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
  13. 13 //抗锯齿
  14. 14 pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  15. 15
  16. 16 //图形轨迹
  17. 17 GraphicsPath gp = new GraphicsPath();
  18. 18 //限定圆形绘制长方形区域
  19. 19 //限定为正方形
  20. 20 Rectangle limitedRec = new Rectangle();
  21. 21 Point startDrawingPoint = new Point(0, 0);
  22. 22 limitedRec.Location = startDrawingPoint;
  23. 23 limitedRec.Size = new Size(Width - 1, Height - 1);
  24. 24
  25. 25 if (IsWeightWidthEqual)
  26. 26 {
  27. 27 int fixedWidth = Width - 1;
  28. 28 Height = Width;
  29. 29 Width = Height;
  30. 30 limitedRec.Size = new Size(fixedWidth, fixedWidth);
  31. 31 }
  32. 32 //以下代码视为了把图片框的显示边界改成圆形
  33. 33 //添加轨迹为椭圆
  34. 34 gp.AddEllipse(limitedRec);
  35. 35 //重新设置边界
  36. 36 Region rg = new Region(gp);
  37. 37 this.Region = rg;
  38. 38 //销毁资源
  39. 39 rg.Dispose();
  40. 40 gp.Dispose();
  41. 41 }

查看代码

鼠标交互事件

  上述5个事件除 OnPaint 之外,其余均为鼠标交互事件

  因为本文对控件闪烁的问题做了处理,所以在重写(Override)此类事件函数时需要添加一个 BufferedGraphics 对象并为之分配空间,最后再使用它来渲染(Render)绘制好的图形至当前控件的 Graphics 画布(/设备)对象(相当于添加一个中间缓冲层将图形绘制完成后再直接覆盖到控件背景上以避免闪烁)

  以下是OnMouseEnter事件的代码:

  1. 1 //1.鼠标进入
  2. 2 protected override void OnMouseEnter(EventArgs e)
  3. 3 {
  4. 4 base.OnMouseEnter(e);
  5. 5 using (Graphics g = Graphics.FromHwnd(this.Handle))
  6. 6 {
  7. 7 // 双三次插值
  8. 8 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  9. 9 // 抗锯齿
  10. 10 g.SmoothingMode = SmoothingMode.AntiAlias;
  11. 11 // 再次以背景色刷新空白图形
  12. 12 buffImgG.Clear(this.BackColor);
  13. 13 // 在空白图形上绘制分割后的第2个小图片
  14. 14 buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
  15. 15 // 依据上述空白图形buffImgG创建缓冲Graphics,指定区域为该控件工作区
  16. 16 BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
  17. 17 // BufferedGraphics绘制整个图形,指定绘制区域为该控件工作区
  18. 18 // 此处推荐使用DrawImageUnscaledAndClipped
  19. 19 buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
  20. 20 // 图形缓冲区写入到当前控件Graphics对象
  21. 21 buff.Render(g);
  22. 22 }
  23. 23 }

查看代码

  其它的鼠标交互事件类似,只是绘制的背景图片不一样而已,即这句代码 buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle); 中的 SplitedImage 索引各有不同,就不一一重复了。

代码汇总

  那么完整的程序应该如何运行呢?

  在VS2010中新建一个解决方案,其中添加2个项目,一个是WinForm窗体应用程序,这个是用来测试控件的;另一个是Windows窗体控件库。窗体控件库默认继承的是 UserControl 这个类,但是在本文笔者将其改为继承 PictureBox 类,即自己做的这个控件还是属于PictureBox这个类型而不是 UserControl

  所以完整的代码如下:

  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.ComponentModel;
  4. 4 using System.Drawing;
  5. 5 using System.Drawing.Drawing2D;
  6. 6
  7. 7 using System.Data;
  8. 8 using System.Linq;
  9. 9 using System.Text;
  10. 10 using System.Windows.Forms;
  11. 11 using System.Diagnostics;
  12. 12 using System.IO;
  13. 13 using System.Security.Cryptography;
  14. 14 using System.Drawing.Imaging;
  15. 15
  16. 16
  17. 17 namespace PicBtn
  18. 18 {
  19. 19 public partial class RoundPictureBox : PictureBox
  20. 20 {
  21. 21 [Category("派生属性"), Description("有的图标是正圆形,因此此处设置控件的长宽是否相等")]
  22. 22 public bool IsWeightWidthEqual { get; set; }
  23. 23 // 该属性尚未使用
  24. 24 [Category("派生属性"), Description("表明是否由多个图片来表示图片框的按钮特效")]
  25. 25 public bool IsMultiImage { get; set; }
  26. 26 // 分割后图片容器
  27. 27 List<Bitmap> SplitedImage = null;
  28. 28
  29. 29 Image buffImg;
  30. 30 Graphics buffImgG;
  31. 31 public RoundPictureBox()
  32. 32 {
  33. 33 InitializeComponent();
  34. 34 //双缓冲区绘制
  35. 35 DoubleBuffered = true;
  36. 36 SizeMode = PictureBoxSizeMode.Normal;
  37. 37 // 图片素材路径,视具体情况而定(可以更改)
  38. 38 this.ImageLocation = @"D:\文档\VS项目\PicButton\view_next.png";
  39. 39 //按钮图片分割
  40. 40 this.Image = Image.FromFile(ImageLocation);
  41. 41 // 图片宽度(Width)164,将其分为4段并放到容器中
  42. 42 SplitedImage = ImageSplit(164, 4);
  43. 43 }
  44. 44
  45. 45
  46. 46 protected override void OnPaint(PaintEventArgs pe)
  47. 47 {
  48. 48 base.OnPaint(pe);
  49. 49 // 创建空图形
  50. 50 buffImg = new Bitmap(Width,Height);
  51. 51 // 根据空图形创建画布Graphics对象
  52. 52 buffImgG = Graphics.FromImage(buffImg);
  53. 53 // 用画布对象,以背景色刷新空图形
  54. 54 buffImgG.Clear(this.BackColor);
  55. 55
  56. 56 //双三次插值
  57. 57 pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
  58. 58 //抗锯齿
  59. 59 pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  60. 60
  61. 61 //图形轨迹
  62. 62 GraphicsPath gp = new GraphicsPath();
  63. 63 //限定圆形绘制长方形区域
  64. 64 //限定为正方形
  65. 65 Rectangle limitedRec = new Rectangle();
  66. 66 Point startDrawingPoint = new Point(0, 0);
  67. 67 limitedRec.Location = startDrawingPoint;
  68. 68 limitedRec.Size = new Size(Width - 1, Height - 1);
  69. 69
  70. 70 if (IsWeightWidthEqual)
  71. 71 {
  72. 72 int fixedWidth = Width - 1;
  73. 73 Height = Width;
  74. 74 Width = Height;
  75. 75 limitedRec.Size = new Size(fixedWidth, fixedWidth);
  76. 76 }
  77. 77 //以下代码是为了把图片框的显示边界改成圆形
  78. 78 //添加轨迹为椭圆
  79. 79 gp.AddEllipse(limitedRec);
  80. 80 //重新设置边界
  81. 81 Region rg = new Region(gp);
  82. 82 this.Region = rg;
  83. 83 //销毁资源
  84. 84 rg.Dispose();
  85. 85 gp.Dispose();
  86. 86 }
  87. 87
  88. 88 //绘制鼠标进入点击并离开的图像
  89. 89 /*
  90. 90 * 完整的点击过程如下(只考虑鼠标左键的情况)
  91. 91 * 1. 鼠标指针进入PictureBox(以下简称“该控件”),触发事件 MouseEnter
  92. 92 * 2. 鼠标按下不动的一瞬间,触发事件 MouseDown
  93. 93 * 3. 鼠标松开一瞬间,触发事件 MouseUp
  94. 94 * 4. 鼠标指针离开该控件,触发事件 MouseLeave
  95. 95 */
  96. 96 //1.鼠标进入
  97. 97 protected override void OnMouseEnter(EventArgs e)
  98. 98 {
  99. 99 base.OnMouseEnter(e);
  100. 100 using (Graphics g = Graphics.FromHwnd(this.Handle))
  101. 101 {
  102. 102 // 双三次插值
  103. 103 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  104. 104 // 抗锯齿
  105. 105 g.SmoothingMode = SmoothingMode.AntiAlias;
  106. 106 // 再次以背景色刷新空白图形
  107. 107 buffImgG.Clear(this.BackColor);
  108. 108 // 在空白图形上绘制分割后的第2个小图片
  109. 109 buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
  110. 110 // 依据上述空白图形buffImgG创建缓冲Graphics,指定区域为该控件工作区
  111. 111 BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
  112. 112 // BufferedGraphics绘制整个图形,指定绘制区域为该控件工作区
  113. 113 // 此处推荐使用DrawImageUnscaledAndClipped
  114. 114 buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
  115. 115 // 图形缓冲区写入到当前控件Graphics对象
  116. 116 buff.Render(g);
  117. 117 }
  118. 118 }
  119. 119 //2.鼠标按下
  120. 120 protected override void OnMouseDown(MouseEventArgs e)
  121. 121 {
  122. 122 base.OnMouseDown(e);
  123. 123 using (Graphics g = Graphics.FromHwnd(this.Handle))
  124. 124 {
  125. 125 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  126. 126 g.SmoothingMode = SmoothingMode.HighQuality;
  127. 127
  128. 128 buffImgG.InterpolationMode = InterpolationMode.HighQualityBicubic;
  129. 129 buffImgG.SmoothingMode = SmoothingMode.HighQuality;
  130. 130 buffImgG.Clear(BackColor);
  131. 131 buffImgG.DrawImageUnscaledAndClipped(SplitedImage[2],ClientRectangle);
  132. 132 BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
  133. 133 buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
  134. 134 buff.Render(g);
  135. 135 }
  136. 136 }
  137. 137
  138. 138 //3. 鼠标按键松开
  139. 139 protected override void OnMouseUp(MouseEventArgs e)
  140. 140 {
  141. 141 base.OnMouseUp(e);
  142. 142 using (Graphics g = Graphics.FromHwnd(this.Handle))
  143. 143 {
  144. 144 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  145. 145 g.SmoothingMode = SmoothingMode.HighQuality;
  146. 146 buffImgG.Clear(BackColor);
  147. 147 buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
  148. 148 BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
  149. 149 buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
  150. 150 buff.Render(g);
  151. 151 }
  152. 152 }
  153. 153
  154. 154 //4.鼠标离开
  155. 155 protected override void OnMouseLeave(EventArgs e)
  156. 156 {
  157. 157 base.OnMouseLeave(e);
  158. 158 using (Graphics g = Graphics.FromHwnd(this.Handle))
  159. 159 {
  160. 160 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  161. 161 g.SmoothingMode = SmoothingMode.HighQuality;
  162. 162
  163. 163 buffImgG.Clear(BackColor);
  164. 164 buffImgG.DrawImageUnscaledAndClipped(SplitedImage[3], ClientRectangle);
  165. 165 BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
  166. 166 buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
  167. 167 buff.Render(g);
  168. 168 }
  169. 169 }
  170. 170
  171. 171 /// <summary>
  172. 172 /// 图片分割函数,此处仅仅按图片宽度来分割
  173. 173 /// </summary>
  174. 174 /// <param name="ImageWidth">图片素材宽度</param>
  175. 175 /// <param name="SegmentsNum">要分割为几段,默认是1段</param>
  176. 176 /// <returns>分割后的图片集合</returns>
  177. 177 private List<Bitmap> ImageSplit(int ImageWidth, int SegmentsNum = 1)
  178. 178 {
  179. 179 // 定义分割后的图片存放容器
  180. 180 List<Bitmap> SplitedImage = new List<Bitmap>();
  181. 181 // 克隆按钮背景图片
  182. 182 Bitmap SrcBmp = new Bitmap(this.Image);
  183. 183 // 指定图片像素格式为ARGB型
  184. 184 PixelFormat ReslouteFormat = PixelFormat.Format32bppArgb;
  185. 185 // 指定分割区域
  186. 186 Rectangle SplitAreaRec = new Rectangle();
  187. 187 // 如果图片尺寸为负值
  188. 188 if (ImageWidth <= 0 || SegmentsNum <= 0)
  189. 189 return SplitedImage;
  190. 190 else
  191. 191 {
  192. 192 // 依据要分割的段数来做循环
  193. 193 // 从 0(含) 到 SegmentsNum - 1(含)
  194. 194 for (int i = 0; i < SegmentsNum; i++)
  195. 195 {
  196. 196 /*
  197. 197 * 在这里要把图片分割为4段小图片,每一段图片大小均为41 * 41
  198. 198 * 以下列举出每个小图片的左上角坐标(即起始坐标)
  199. 199 * (0, 0)
  200. 200 * (41, 0)
  201. 201 * (82, 0)
  202. 202 * (123, 0)
  203. 203 * Y 坐标均为 0
  204. 204 *
  205. 205 * 计算每个小图片的宽度:ImageWidth / SegmentsNum (总宽度/要分割的段数)
  206. 206 * 因此 X = i * (ImageWidth / SegmentsNum)
  207. 207 */
  208. 208 SplitAreaRec.X = 0 + i * (ImageWidth / SegmentsNum);
  209. 209 SplitAreaRec.Y = 0;
  210. 210 // 小图片为正方形,所以以下这两个值一样
  211. 211 SplitAreaRec.Width = ImageWidth / SegmentsNum;
  212. 212 SplitAreaRec.Height = ImageWidth / SegmentsNum;
  213. 213 // 以指定的像素格式,克隆分割的图像
  214. 214 Bitmap SplitedBmp = SrcBmp.Clone(SplitAreaRec, ReslouteFormat);
  215. 215 // 添加进集合
  216. 216 SplitedImage.Add(SplitedBmp);
  217. 217 }
  218. 218 GC.Collect();
  219. 219 return SplitedImage;
  220. 220 }
  221. 221 }
  222. 222 }
  223. 223 }

RoundPictureBox.cs

  还有设计器的代码:

  1. 1 using System.Windows.Forms;
  2. 2 namespace PicBtn
  3. 3 {
  4. 4 partial class RoundPictureBox
  5. 5 {
  6. 6 /// <summary>
  7. 7 /// 必需的设计器变量。
  8. 8 /// </summary>
  9. 9 private System.ComponentModel.IContainer components = null;
  10. 10
  11. 11 /// <summary>
  12. 12 /// 清理所有正在使用的资源。
  13. 13 /// </summary>
  14. 14 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
  15. 15 protected override void Dispose(bool disposing)
  16. 16 {
  17. 17 if (disposing && (components != null))
  18. 18 {
  19. 19 components.Dispose();
  20. 20 }
  21. 21 base.Dispose(disposing);
  22. 22 }
  23. 23
  24. 24 #region 组件设计器生成的代码
  25. 25
  26. 26 /// <summary>
  27. 27 /// 设计器支持所需的方法 - 不要
  28. 28 /// 使用代码编辑器修改此方法的内容。
  29. 29 /// </summary>
  30. 30 private void InitializeComponent()
  31. 31 {
  32. 32 components = new System.ComponentModel.Container();
  33. 33 // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  34. 34 SetStyle(ControlStyles.UserPaint, true);
  35. 35 SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
  36. 36 SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
  37. 37 SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//解决闪烁
  38. 38 UpdateStyles();
  39. 39 }
  40. 40
  41. 41 #endregion
  42. 42 }
  43. 43 }

RoundPictureBox.Designer.cs

  在生成解决方案之后,需要在窗体应用程序项目中引用控件库的项目,会在窗体设计器工具箱中看见自己写的这个图片按钮控件,如下图

  最后把这个控件拖到自己窗体上即可,再调试、运行并观察结果,效果动态图在引言部分

#cnblogs_post_body h1 { background: rgba(0, 0, 0, 1); border-radius: 6px; box-shadow: 0 0 1px rgba(95, 90, 75, 1), 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: rgba(255, 255, 255, 1); font-family: "微软雅黑", "宋体", "黑体", Arial; font-size: 20px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 5px 0 5px 10px; text-shadow: 2px 2px 3px rgba(34, 34, 34, 1) }
#cnblogs_post_body h2 { background: rgba(43, 102, 149, 1); border-radius: 6px; box-shadow: 0 0 1px rgba(95, 90, 75, 1), 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: rgba(255, 255, 255, 1); font-family: "微软雅黑", "宋体", "黑体", Arial; font-size: 18px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 5px 0 5px 10px; text-shadow: 2px 2px 3px rgba(34, 34, 34, 1) }
#cnblogs_post_body h3 { background: rgba(91, 150, 0, 1); border-radius: 6px; box-shadow: 0 0 1px rgba(95, 90, 75, 1), 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: rgba(255, 255, 255, 1); font-family: "微软雅黑", "宋体", "黑体", Arial; font-size: 12px; font-weight: bold; height: 21px; line-height: 21px; margin: 12px 0 !important; padding: 5px 0 5px 10px; text-shadow: 2px 2px 3px rgba(34, 34, 34, 1) }

C# 使用PictureBox实现图片按钮控件的更多相关文章

  1. Android控件之Button(按钮控件)和ImageButton(图片按钮控件)

    一.Button和ImageButton特证: 1.共同特证: 都可以作为一个按钮产生点击事件 2.不同特证: Button有text的属性,ImageButton没有 ImageButton有src ...

  2. Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子

    Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子 procedure TForm1.Button1Click(Sender: TObject); ...

  3. MFC基于对话框风格按钮控件添加图片的方法(大神止步)

    菜鸟还在研究这个东西,大神就不要看了.一直都在觉得用VC或VS建立的对话框总是全灰色感觉太单调了,如果可以在上面添加一些漂亮的图片就好了,今天终于实现了.其实挺简单的,下面就分几个步骤讲一下: 第一步 ...

  4. Qt中,将以png为格式的图片在按钮控件上显示

    在Qt编程中,我们常常会遇见这样或那样的小问题,这里,我介绍一个将png为格式的图片在按钮控件上显示的小功能. resistanceBtn = new QPushButton(element); re ...

  5. UI-UIImageView的图片填充方式(contentMode)_图片作为控件背景图的拉伸方式(stretch)介绍

    常用图片填充方式 这里只介绍三个最常用的图片填充方式 UIViewContentModeScaleToFill模式会导致图片变形.例如: UIViewContentModeScaleAspectFit ...

  6. VC按钮控件实现指示灯效果

    VC为按钮控件添加图片的方法有很多种: 直接调用SetBitmap:  CButton pButton->SetBitmap(hBitmap); 使用CButtonST控件: 使用CDC: 使用 ...

  7. 关于在storyboard拖按钮控件,手动设置代码不成功的问题

    首先,在 storyboard 中拖拽一个按钮控件.设置好约束条件

  8. 我写的一个 Qt 显示图片的控件

    Qt 中没有专门显示图片的控件.通常我们会使用QLabel来显示图片.可是QLabel 显示图片的能力还是有点弱.比方不支持图像的缩放一类的功能.使用起来不是非常方便. 因此我就自己写了个简单的类. ...

  9. Qt编写自定义控件11-设备防区按钮控件

    前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...

随机推荐

  1. 前端学习总结之——HTML

    近期在找工作参加面试,想总结一下学过的东西,也会持续更新遇到的新问题.盲点. 什么是HTML? 超文本标记语言(英语:HyperText Markup Language,简称:HTML),由尖括号包围 ...

  2. 转载-notepad++ zend-coding使用

    转载-notepad++ zend-coding使用   zen-Coding是一款快速编写HTML,CSS(或其他格式化语言)代码的编辑器插件,这个插件可以用缩写方式完成大量重复的编码工作,是web ...

  3. 瞄到BindingGroup用法

    文章转载于https://www.cnblogs.com/dangnianxiaoqingxin/p/12653988.html 2.BindingGroup的使用 public class MyCl ...

  4. 【C++】《Effective C++》第二章

    第二章 构造/析构/赋值运算 条款05:了解C++默默编写并调用哪些函数 默认函数 一般情况下,编译器会为类默认合成以下函数:default构造函数.copy构造函数.non-virtual析构函数. ...

  5. Hbase 手动执行MajorCompation

    说明: Major Compaction 的作用: 1.将一个Region下的所有StoreFile合并成一个StoreFile文件 2.对于删除.过期.多余版本的数据进行清除 由于MajorComp ...

  6. CTFshow-萌新赛杂项_签到

    查看网页信息 http://game.ctf.show/r2/ 把网页源码下载后发现有大片空白 使用winhex打开 把这些16进制数值复制到文件中 把20替换为0,09替换为1后 得到一串二进制数值 ...

  7. [java]文件上传下载删除与图片预览

    图片预览 @GetMapping("/image") @ResponseBody public Result image(@RequestParam("imageName ...

  8. 在.NET Core 中实现健康检查

    .NET Core中提供了开箱即用的运行状况检查,首先,我将在.NET Core API应用程序中执行运行状况检查,接下来,我们将使用DbContext集成SQL Server或数据库的运行状况检查, ...

  9. JVM(八)执行引擎相关内容

    一:两种解释器 JAVA字节码解释器: java字节码===>c++代码==>硬编码. 首先.java文件编译成字节码,遍历每行的字节码指令,因为每个字节码指令的含义都是固定的所以可以根据 ...

  10. STP 根桥、根端口、指定端口是如何选举的

    学习HCIA过程中,对交换机的根桥.跟端口以及指定端口选举有些迷糊,也度娘了一番,总觉得一部分人解释的不够全面精细.通过仔细研究最终有了自己的理解,分享给大家,如果纰漏,欢迎指正. STP收敛过程: ...