最近需要做一个圆形的按钮,去CodeProject找了一下,发现有现成的可用,但不能完全满足我的需求。因此自己试着利用WinForm中的自定义组件功能,制作一个圆形按钮。圆形按钮小制作即将开始之前,先来看看最终效果(Demo程序下载链接:http://download.csdn.net/detail/keypig_zz/9440806)
下面分两步制作这个按钮。
A. 目标
想了一下,即将制作的圆形按钮需要满足几个要求:
i. 按钮呈现圆形或椭圆形,具体形状参数可调;
ii. 按钮用不同的填充色来响应鼠标进入或者离开事件;
iii. 按钮通过改变边的颜色来显示是否获取焦点状态;
iv. 按钮通过改变填充色的亮度来区分按钮是否按下。
B. 实现代码
具体的制作思路大致如下:
i. 成员变量:
(a).按钮绘制区域矩形 Rectangle rect;
(b).鼠标书否进入 bool buttonEnter;
(c).鼠标是否按下 bool buttonPressed;
(d).按钮是否被点击 bool buttonClicked。
ii. 属性:
(a).形状;
(b).填充色;
(c).边框。
iii. 构造函数
(a).按钮风格设定;
(b).成员变量初始化;
iv. 部分函数重写
(a).控件绘制OnPaint;
(b).鼠标相关函数;
v. 自定义函数
(a).图案填充;
(b).绘制边框;
(c).调整控件大小;
代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Diagnostics; 5 using System.Linq; 6 using System.Text; 7 8 using System.Windows.Forms; 9 using System.Drawing; 10 using System.Drawing.Drawing2D; 11 12 namespace 章鱼.Forms 13 { 14 public partial class RoundButton : Button 15 { 16 #region --成员变量-- 17 18 RectangleF rect = new RectangleF();//控件矩形 19 bool mouseEnter;//鼠标是否进入控件区域的标志 20 bool buttonPressed;//按钮是否按下 21 bool buttonClicked;//按钮是否被点击 22 #endregion 23 24 #region --属性-- 25 26 #region 形状 27 28 /// <summary> 29 /// 设置或获取圆形按钮的圆的边距离方框边的距离 30 /// </summary> 31 [Browsable(true), DefaultValue(2)] 32 [Category("Appearance")] 33 public int DistanceToBorder { get; set; } 34 35 #endregion 36 37 #region 填充色 38 39 /// <summary> 40 /// 获取或设置按钮主体颜色 41 /// </summary> 42 /// <value>The color of the focus.</value> 43 [Browsable(true), DefaultValue(typeof(Color), "DodgerBlue"), Description("按钮主体渐变起始颜色")] 44 [Category("Appearance")] 45 public Color ButtonCenterColorEnd { get; set; } 46 47 /// <summary> 48 /// 获取或设置按钮主体颜色 49 /// </summary> 50 [Browsable(true), DefaultValue(typeof(Color), "CornflowerBlue"), Description("按钮主体渐变终点颜色")] 51 [Category("Appearance")] 52 public Color ButtonCenterColorStart { get; set; } 53 54 /// <summary> 55 /// 获取或设置按钮主体颜色渐变方向 56 /// </summary> 57 [Browsable(true), DefaultValue(90),Description("按钮主体颜色渐变方向,X轴顺时针开始")] 58 [Category("Appearance")] 59 public int GradientAngle { get; set; } 60 61 /// <summary> 62 /// 是否显示中间标志 63 /// </summary> 64 [Browsable(true), DefaultValue(typeof(bool), "true"), Description("是否显示中间标志")] 65 [Category("Appearance")] 66 public bool IsShowIcon { get; set; } 67 68 /// <summary> 69 /// 按钮中间标志填充色 70 /// </summary> 71 [Browsable(true), DefaultValue(typeof(Color), "Black"), Description("按钮中间标志填充色")] 72 [Category("Appearance")] 73 public Color IconColor { get; set; } 74 75 76 #endregion 77 78 #region 边框 79 80 /// <summary> 81 /// 获取或设置边框大小 82 /// </summary> 83 [Browsable(true), DefaultValue(4), Description("按钮边框大小")] 84 [Category("Appearance")] 85 public int BorderWidth { get; set; } 86 87 /// <summary> 88 /// 获取或设置按钮边框颜色 89 /// </summary> 90 /// <value>The color of the focus.</value> 91 [Browsable(true), DefaultValue(typeof(Color), "Black"), Description("按钮边框颜色")] 92 [Category("Appearance")] 93 public Color BorderColor { get; set; } 94 95 /// <summary> 96 /// 获取或设置边框透明度 97 /// </summary> 98 [Browsable(true), DefaultValue(200),Description("设置边框透明度:0-255")] 99 [Category("Appearance")] 100 public int BorderTransparent { get; set; } 101 102 /// <summary> 103 /// 获取或设置按钮获取焦点后边框颜色 104 /// </summary> 105 /// <value>The color of the focus.</value> 106 [Browsable(true), DefaultValue(typeof(Color), "Orange"), Description("按钮获得焦点后的边框颜色")] 107 [Category("Appearance")] 108 public Color FocusBorderColor { get; set; } 109 110 #endregion 111 112 #endregion 113 114 #region --构造函数-- 115 /// <summary> 116 /// 构造函数 117 /// </summary> 118 public RoundButton() 119 { 120 // 控件风格 121 SetStyle(ControlStyles.SupportsTransparentBackColor, true); 122 SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 123 SetStyle(ControlStyles.AllPaintingInWmPaint, true); 124 SetStyle(ControlStyles.ResizeRedraw, true); 125 SetStyle(ControlStyles.UserPaint, true); 126 //初始值设定 127 this.Height = this.Width = 80; 128 129 DistanceToBorder = 4; 130 ButtonCenterColorStart = Color.CornflowerBlue; 131 ButtonCenterColorEnd = Color.DodgerBlue; 132 BorderColor = Color.Black; 133 FocusBorderColor = Color.Orange; 134 IconColor = Color.Black; 135 BorderWidth = 4; 136 BorderTransparent = 200; 137 GradientAngle = 90; 138 139 mouseEnter = false; 140 buttonPressed = false; 141 buttonClicked = false; 142 IsShowIcon = true; 143 144 InitializeComponent(); 145 } 146 #endregion 147 148 #region --重写部分事件-- 149 150 #region OnPaint事件 151 152 /// <summary> 153 /// 控件绘制 154 /// </summary> 155 /// <param name="pevent"></param> 156 protected override void OnPaint(PaintEventArgs pevent) 157 { 158 //base.OnPaint(pevent); 159 base.OnPaintBackground(pevent); 160 161 Graphics g = pevent.Graphics; 162 g.InterpolationMode = InterpolationMode.HighQualityBicubic; 163 g.SmoothingMode = SmoothingMode.AntiAlias;//抗锯齿 164 165 myResize();//调整圆形区域 166 167 var brush = new LinearGradientBrush(rect, ButtonCenterColorStart, ButtonCenterColorEnd, GradientAngle); 168 169 PaintShape(g, brush, rect);//绘制按钮中心区域 170 171 DrawBorder(g);//绘制边框 172 173 DrawStateIcon(g);//绘制按钮功能标志 174 175 if (mouseEnter) 176 { 177 DrawHighLight(g);//绘制高亮区域 178 DrawStateIcon(g);//绘制按钮功能标志 179 } 180 181 } 182 183 #endregion 184 185 #region 鼠标 186 187 /// <summary> 188 /// 鼠标点击事件 189 /// </summary> 190 /// <param name="e"></param> 191 protected override void OnMouseClick(MouseEventArgs e) 192 { 193 base.OnMouseClick(e); 194 buttonClicked = !buttonClicked; 195 } 196 /// <summary> 197 /// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"/> event. 198 /// </summary> 199 /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param> 200 protected override void OnMouseUp(MouseEventArgs e) 201 { 202 base.OnMouseUp(e); 203 if (e.Button != MouseButtons.Left) return; 204 buttonPressed = false; 205 base.Invalidate(); 206 } 207 208 /// <summary> 209 /// Raises the <see cref="E:System.Windows.Forms.Control.MouseDown"/> event. 210 /// </summary> 211 /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param> 212 protected override void OnMouseDown(MouseEventArgs e) 213 { 214 base.OnMouseDown(e); 215 if (e.Button != MouseButtons.Left) return; 216 buttonPressed = true; 217 } 218 219 /// <summary> 220 /// 鼠标进入按钮 221 /// </summary> 222 /// <param name="e"></param> 223 protected override void OnMouseEnter(EventArgs e) 224 { 225 base.OnMouseEnter(e); 226 mouseEnter = true; 227 } 228 229 /// <summary> 230 /// 鼠标离开控件 231 /// </summary> 232 /// <param name="e"></param> 233 protected override void OnMouseLeave(EventArgs e) 234 { 235 base.OnMouseLeave(e); 236 mouseEnter = false; 237 } 238 239 #endregion 240 #endregion 241 242 #region --自定义函数-- 243 244 private void DrawStateIcon(Graphics g) 245 { 246 if (IsShowIcon) 247 { 248 if (buttonClicked) 249 { 250 GraphicsPath startIconPath = new GraphicsPath(); 251 int W = base.Width / 3; 252 Point p1 = new Point(W, W); 253 Point p2 = new Point(2 * W, W); 254 Point p3 = new Point(2 * W, 2 * W); 255 Point p4 = new Point(W, 2 * W); 256 Point[] pts = { p1, p2, p3, p4 }; 257 startIconPath.AddLines(pts); 258 Brush brush = new SolidBrush(IconColor); 259 g.FillPath(brush, startIconPath); 260 } 261 else 262 { 263 GraphicsPath stopIconPath = new GraphicsPath(); 264 int W = base.Width / 4; 265 Point p1 = new Point(3 * W / 2, W); 266 Point p2 = new Point(3 * W / 2, 3 * W); 267 Point p3 = new Point(3 * W, 2 * W); 268 Point[] pts = { p1, p2, p3, }; 269 stopIconPath.AddLines(pts); 270 Brush brush = new SolidBrush(IconColor); 271 g.FillPath(brush, stopIconPath); 272 } 273 } 274 } 275 276 /// <summary> 277 /// 重新确定控件大小 278 /// </summary> 279 protected void myResize() 280 { 281 int x = DistanceToBorder; 282 int y = DistanceToBorder; 283 int width = this.Width - 2 * DistanceToBorder; 284 int height = this.Height - 2 * DistanceToBorder; 285 rect = new RectangleF(x, y, width, height); 286 } 287 288 /// <summary> 289 /// 绘制高亮效果 290 /// </summary> 291 /// <param name="g">The graphics object</param> 292 protected virtual void DrawHighLight(Graphics g) 293 { 294 RectangleF highlightRect = rect; 295 highlightRect.Inflate(-BorderWidth/2, -BorderWidth/2); 296 Brush brush = Brushes.DodgerBlue; 297 if (buttonPressed) 298 { 299 brush = new LinearGradientBrush(rect, ButtonCenterColorStart, ButtonCenterColorEnd, GradientAngle); 300 } 301 302 else 303 { 304 brush = new LinearGradientBrush(rect, Color.FromArgb(60, Color.White), 305 Color.FromArgb(60, Color.White), GradientAngle); 306 } 307 PaintShape(g, brush, highlightRect); 308 } 309 310 /// <summary> 311 /// 绘制边框 312 /// </summary> 313 /// <param name="g">Graphics对象</param> 314 protected virtual void DrawBorder(Graphics g) 315 { 316 Pen p=new Pen(BorderColor); 317 if (Focused) 318 { 319 p.Color = FocusBorderColor;//外圈获取焦点后的颜色 320 p.Width = BorderWidth; 321 PaintShape(g, p, rect); 322 } 323 else 324 { 325 p.Width = BorderWidth; 326 PaintShape(g, p, rect); 327 } 328 329 } 330 331 /// <summary> 332 /// 333 /// </summary> 334 /// <param name="g">The graphics object</param> 335 protected virtual void DrawPressState(Graphics g) 336 { 337 RectangleF pressedRect = rect; 338 pressedRect.Inflate(-2, -2); 339 Brush brush = new LinearGradientBrush(rect, Color.FromArgb(60, Color.White), 340 Color.FromArgb(60, Color.White), GradientAngle); 341 PaintShape(g, brush, pressedRect); 342 } 343 344 /// <summary> 345 /// 绘制图形 346 /// </summary> 347 /// <param name="g">Graphics对象</param> 348 /// <param name="pen">Pen对象</param> 349 /// <param name="rect">RectangleF对象</param> 350 protected virtual void PaintShape(Graphics g, Pen pen, RectangleF rect) 351 { 352 g.DrawEllipse(pen, rect); 353 } 354 355 /// <summary> 356 /// 绘制图形 357 /// </summary> 358 /// <param name="g">Graphics对象</param> 359 /// <param name="brush">Brush对象</param> 360 /// <param name="rect">Rectangle对象</param> 361 protected virtual void PaintShape(Graphics g, Brush brush, RectangleF rect) 362 { 363 g.FillEllipse(brush, rect); 364 365 } 366 367 #endregion 368 } 369 }
(^_^)
时间: 2024-11-23 11:34:30