WinForm(C#)自定义控件之——RoundButton(圆形按钮)

最近需要做一个圆形的按钮,去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

WinForm(C#)自定义控件之——RoundButton(圆形按钮)的相关文章

winform制作自定义控件(入门)

原文链接:http://blog.csdn.net/bychentufeiyang/article/details/7081402   与原文基本一致,只是例子变成VS2012环境,语言采用博主常用的VB.NET 一 .概述Windows 窗体控件是可再次使用的组件,它们封装了用户界面功能,并且可以用于客户端 Windows 应用程序.“Windows 窗体”不仅提供了许多现成控件,还提供了自行开发控件的基础结构.可以组合现有控件.扩展现有控件或创作自己的自定义控件.Windows 窗体控件是从

WinForm GDI+自定义控件总结(一)

前言 由于项目的原因好久没写博客了,也正是项目的原因开始系统的学习WinForm,从而接触到自定义控件的开发.自定义控件的开发有一定的难度,对开发者要求比较高,需要了解Windows运行的机制,熟悉win32Api和GDI+.下面是我收集的一些资料,挺不错的. 资料 .NET组件编程http://www.cnblogs.com/mapserver/category/57177.html .NET组件编程(1) 基础.NET组件编程(2) PropertyAttribute和EventAttrib

winform制作自定义控件

一 .概述Windows 窗体控件是可再次使用的组件,它们封装了用户界面功能,并且可以用于客户端 Windows 应用程序.“Windows 窗体”不仅提供了许多现成控件,还提供了自行开发控件的基础结构.可以组合现有控件.扩展现有控件或创作自己的自定义控件.Windows 窗体控件是从 System.Windows.Forms.Control 直接或间接派生的类.以下列表描述了开发 Windows 窗体控件的常见方案: ·  组合现有控件来创作一个复合控件. 复合控件封装有一个可以作为控件重复使

winform之自定义控件

这样的一个控件 肯定得通过自定义控件来实现了 public class ProcessLabel : Control { public ProcessLabel() { //InitializeComponent(); this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPain

WinForm创建自定义控件

虽然VS为我们提供了很多控件可以使用,但有时候这些控件仍然不能满足我们的要求,比如我们要对部分控件进行一些个性化的定制,例如美化控件,这时候就需要自己绘制控件,或是在原有控件的基础上进行修改 自定义控件分为三种 1.组合控件(CompositeControls):在原有控件的基础上根据需要进行组合 2.扩展控件(ExtendedControls):继承自原有控件,添加一些新的属性和方法,绘制一些新元素 3.自定义控件(CustomControls):控件的绘制全部由用户定义 1.组合控件 新建项

winform窗体自定义控件

先上代码!!! 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 10 using System.Reflection; 11 namespace

WinForm用户自定义控件,在主窗体加载时出现闪烁;调用用户控件出现闪烁,需要鼠标才能够显示

转载自:http://www.dotblogs.com.tw/rainmaker/archive/2012/02/22/69811.aspx 解决方案: 在调用用户控件的窗体里面添加一下代码: protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp

在WPF中自定义控件

一, 不一定需要自定义控件在使用WPF以前,动辄使用自定义控件几乎成了惯性思维,比如需要一个带图片的按钮,但在WPF中此类任务却不需要如此大费周章,因为控件可以嵌套使用以及可以为控件外观打造一套新的样式就可以了.是否需要我们来自定义控件,这需要你考虑目前已有控件的真正逻辑功能而不要局限于外观,如果目前的控件都不能直觉地表达你的想法,那么你可以自己来打造一个控件,否则,也许我们仅仅改变一下目前控件的模板等就可以完成任务.很多人在自定义控件上经常犯的错误是:重复撰写已有的逻辑 二,UserContr

Java进击C#——应用开发之Asp.net

本章简言 上一章中笔者讲到关于Linq和EF的用法.并以hibernate来进行讲解.那么本章笔者来讲一下C#的Asp.Net.即是在B/S模式下开发.现在企业大部分的业务都是面向B/S模式的.所以对于Asp.Net的了解变得必不可少的知识点.笔者在从事JAVA开发的时候,很少看到有关于Awt和Swing开发的企业.更多是Servlet和JSP开发.这也是没有办法的事情.因为用Awt和Swing来开发软件不是说不能.只是怕吃力不讨好.笔者不是说JAVA不好.有一些方面JAVA的确存在不适合的情况