最近須要作一個圓形的按鈕,去CodeProject找了一下,發現有現成的可用,但不能徹底知足個人需求。所以本身試着利用WinForm中的自定義組件功能,製做一個圓形按鈕。圓形按鈕小製做即將開始以前,先來看看最終效果(Demo程序下載連接:http://download.csdn.net/detail/keypig_zz/9440806)ide
下面分兩步製做這個按鈕。函數
A. 目標this
想了一下,即將製做的圓形按鈕須要知足幾個要求:spa
i. 按鈕呈現圓形或橢圓形,具體形狀參數可調;.net
ii. 按鈕用不一樣的填充色來響應鼠標進入或者離開事件;3d
iii. 按鈕經過改變邊的顏色來顯示是否獲取焦點狀態;code
iv. 按鈕經過改變填充色的亮度來區分按鈕是否按下。orm
B. 實現代碼對象
具體的製做思路大體以下:blog
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 #endregion 183 184 #region 鼠標 185 186 /// <summary> 187 /// 鼠標點擊事件 188 /// </summary> 189 /// <param name="e"></param> 190 protected override void OnMouseClick(MouseEventArgs e) 191 { 192 base.OnMouseClick(e); 193 buttonClicked = !buttonClicked; 194 } 195 /// <summary> 196 /// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"/> event. 197 /// </summary> 198 /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param> 199 protected override void OnMouseUp(MouseEventArgs e) 200 { 201 base.OnMouseUp(e); 202 if (e.Button != MouseButtons.Left) return; 203 buttonPressed = false; 204 base.Invalidate(); 205 } 206 207 /// <summary> 208 /// Raises the <see cref="E:System.Windows.Forms.Control.MouseDown"/> event. 209 /// </summary> 210 /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param> 211 protected override void OnMouseDown(MouseEventArgs e) 212 { 213 base.OnMouseDown(e); 214 if (e.Button != MouseButtons.Left) return; 215 buttonPressed = true; 216 } 217 218 /// <summary> 219 /// 鼠標進入按鈕 220 /// </summary> 221 /// <param name="e"></param> 222 protected override void OnMouseEnter(EventArgs e) 223 { 224 base.OnMouseEnter(e); 225 mouseEnter = true; 226 } 227 228 /// <summary> 229 /// 鼠標離開控件 230 /// </summary> 231 /// <param name="e"></param> 232 protected override void OnMouseLeave(EventArgs e) 233 { 234 base.OnMouseLeave(e); 235 mouseEnter = false; 236 } 237 238 #endregion 239 #endregion 240 241 #region --自定義函數-- 242 243 /// <summary> 244 /// 繪製中心區域標誌 245 /// </summary> 246 /// <param name="g"></param> 247 private void DrawStateIcon(Graphics g) 248 { 249 if (IsShowIcon) 250 { 251 if (buttonClicked) 252 { 253 GraphicsPath startIconPath = new GraphicsPath(); 254 int W = base.Width / 3; 255 Point p1 = new Point(W, W); 256 Point p2 = new Point(2 * W, W); 257 Point p3 = new Point(2 * W, 2 * W); 258 Point p4 = new Point(W, 2 * W); 259 Point[] pts = { p1, p2, p3, p4 }; 260 startIconPath.AddLines(pts); 261 Brush brush = new SolidBrush(IconColor); 262 g.FillPath(brush, startIconPath); 263 } 264 else 265 { 266 GraphicsPath stopIconPath = new GraphicsPath(); 267 int W = base.Width / 4; 268 Point p1 = new Point(3 * W / 2, W); 269 Point p2 = new Point(3 * W / 2, 3 * W); 270 Point p3 = new Point(3 * W, 2 * W); 271 Point[] pts = { p1, p2, p3, }; 272 stopIconPath.AddLines(pts); 273 Brush brush = new SolidBrush(IconColor); 274 g.FillPath(brush, stopIconPath); 275 } 276 } 277 } 278 279 /// <summary> 280 /// 從新肯定控件大小 281 /// </summary> 282 protected void myResize() 283 { 284 int x = DistanceToBorder; 285 int y = DistanceToBorder; 286 int width = this.Width - 2 * DistanceToBorder; 287 int height = this.Height - 2 * DistanceToBorder; 288 rect = new RectangleF(x, y, width, height); 289 } 290 291 /// <summary> 292 /// 繪製高亮效果 293 /// </summary> 294 /// <param name="g">Graphic對象</param> 295 protected virtual void DrawHighLight(Graphics g) 296 { 297 RectangleF highlightRect = rect; 298 highlightRect.Inflate(-BorderWidth / 2, -BorderWidth / 2); 299 Brush brush = Brushes.DodgerBlue; 300 if (buttonPressed) 301 { 302 brush = new LinearGradientBrush(rect, ButtonCenterColorStart, ButtonCenterColorEnd, GradientAngle); 303 } 304 305 else 306 { 307 brush = new LinearGradientBrush(rect, Color.FromArgb(60, Color.White), 308 Color.FromArgb(60, Color.White), GradientAngle); 309 } 310 PaintShape(g, brush, highlightRect); 311 } 312 313 /// <summary> 314 /// 繪製邊框 315 /// </summary> 316 /// <param name="g">Graphics對象</param> 317 protected virtual void DrawBorder(Graphics g) 318 { 319 Pen p = new Pen(BorderColor); 320 if (Focused) 321 { 322 p.Color = FocusBorderColor;//外圈獲取焦點後的顏色 323 p.Width = BorderWidth; 324 PaintShape(g, p, rect); 325 } 326 else 327 { 328 p.Width = BorderWidth; 329 PaintShape(g, p, rect); 330 } 331 332 } 333 334 /// <summary> 335 /// 336 /// </summary> 337 /// <param name="g">Graphic對象</param> 338 protected virtual void DrawPressState(Graphics g) 339 { 340 RectangleF pressedRect = rect; 341 pressedRect.Inflate(-2, -2); 342 Brush brush = new LinearGradientBrush(rect, Color.FromArgb(60, Color.White), 343 Color.FromArgb(60, Color.White), GradientAngle); 344 PaintShape(g, brush, pressedRect); 345 } 346 347 /// <summary> 348 /// 繪製圖形 349 /// </summary> 350 /// <param name="g">Graphics對象</param> 351 /// <param name="pen">Pen對象</param> 352 /// <param name="rect">RectangleF對象</param> 353 protected virtual void PaintShape(Graphics g, Pen pen, RectangleF rect) 354 { 355 g.DrawEllipse(pen, rect); 356 } 357 358 /// <summary> 359 /// 繪製圖形 360 /// </summary> 361 /// <param name="g">Graphics對象</param> 362 /// <param name="brush">Brush對象</param> 363 /// <param name="rect">Rectangle對象</param> 364 protected virtual void PaintShape(Graphics g, Brush brush, RectangleF rect) 365 { 366 g.FillEllipse(brush, rect); 367 } 368 369 #endregion 370 } 371 }
(^_^)