努力学习,努力工作,爱家,爱国

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

这段时间做了个小项目,需要用到一个背景透明,只显示图片和文字的Button,没有找到现成的,所以自己写了一个,主要就是重写OnPaint事件

下面是这个Button的代码,

其中,是否有选中状态是指按钮按下之后是否有类似于菜单的那中选中状态,同级别之间是否互斥是指当同一空间内有多个Button时,点击某一个是否取消其他按钮的选中状态

  1 /***********************Created By Liushufeng 2011-08-18********************/
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Text;
  5 using System.Windows.Forms;
  6 using System.Drawing;
  7 using System.ComponentModel;
  8 using System.Drawing.Drawing2D;
  9 
 10 namespace OurControls
 11 {
 12     public class OurButton : Label
 13     {
 14         private bool isMouseIn;
 15 
 16         private bool isMouseDown;
 17 
 18         private bool withBorder = true;
 19 
 20         private bool roundCorner = true;
 21 
 22         private bool withArrow = true;
 23 
 24         private int intervalBetweenTextAndBorder = 2;
 25 
 26         private int intervalBetweenTextAndImage = 2;
 27 
 28         private Color colorMouseIn = Color.White;
 29 
 30         private Color colorMouseDown = Color.White;
 31 
 32         private bool haveCheckState = true;
 33 
 34         private bool exclusion = true;
 35 
 36         private eTextPosition textPosition = eTextPosition.Bottom;
 37 
 38         [CategoryAttribute("文字位置"), Browsable(true), DisplayName("文字位置"), DescriptionAttribute("文字位置")]
 39         public eTextPosition TextPosition
 40         {
 41             get { return textPosition; }
 42             set
 43             {
 44                 textPosition = value;
 45                 this.Invalidate();
 46             }
 47         }
 48 
 49         [CategoryAttribute("绘制边框"), Browsable(true), DisplayName("绘制边框"), DescriptionAttribute("绘制边框")]
 50         public bool WithBorder
 51         {
 52             get { return withBorder; }
 53             set
 54             {
 55                 withBorder = value;
 56                 this.Invalidate();
 57             }
 58         }
 59 
 60         [CategoryAttribute("圆角"), Browsable(true), DisplayName("圆角"), DescriptionAttribute("圆角")]
 61         public bool RoundCorner
 62         {
 63             get { return roundCorner; }
 64             set
 65             {
 66                 roundCorner = value;
 67                 this.Invalidate();
 68             }
 69         }
 70 
 71         [CategoryAttribute("带向下的剪头"), Browsable(true), DisplayName("带向下的剪头"), DescriptionAttribute("带向下的剪头")]
 72         public bool WithArrow
 73         {
 74             get { return withArrow; }
 75             set
 76             {
 77                 withArrow = value;
 78                 this.Invalidate();
 79             }
 80         }
 81 
 82         [CategoryAttribute("文字与图像之间的间隔"), Browsable(true), DisplayName("文字与图像之间的间隔"), DescriptionAttribute("文字与图像之间的间隔")]
 83         public int IntervalBetweenTextAndImage
 84         {
 85             get { return intervalBetweenTextAndImage; }
 86             set
 87             {
 88                 intervalBetweenTextAndImage = value;
 89                 this.Invalidate();
 90             }
 91         }
 92 
 93         [CategoryAttribute("文字与边框之间的间隔"), Browsable(true), DisplayName("文字与边框之间的间隔"), DescriptionAttribute("文字与边框之间的间隔")]
 94         public int IntervalBetweenTextAndBorder
 95         {
 96             get { return intervalBetweenTextAndBorder; }
 97             set
 98             {
 99                 intervalBetweenTextAndBorder = value;
100                 this.Invalidate();
101             }
102         }
103 
104         [CategoryAttribute("鼠标悬停时的背景色"), Browsable(true), DisplayName("鼠标悬停时的背景色"), DescriptionAttribute("鼠标悬停时的背景色")]
105         public Color  ColorMouseIn
106         {
107             get { return colorMouseIn; }
108             set { colorMouseIn = value; }
109         }
110 
111         [CategoryAttribute("选中状态的背景色"), Browsable(true), DisplayName("选中状态的背景色"), DescriptionAttribute("选中状态的背景色")]
112         public Color ColorMouseDown
113         {
114             get { return colorMouseDown; }
115             set { colorMouseDown = value; }
116         }
117 
118         [CategoryAttribute("是否有选中状态"), Browsable(true), DisplayName("是否有选中状态"), DescriptionAttribute("是否有选中状态")]
119         public bool CheckState
120         {
121             get { return haveCheckState; }
122             set { haveCheckState = value; }
123         }
124 
125         [CategoryAttribute("同级别之间是否互斥"), Browsable(true), DisplayName("同级别之间是否互斥"), DescriptionAttribute("同级别之间是否互斥")]
126         public bool Exclusion
127         {
128             get { return exclusion; }
129             set { exclusion= value; }
130         }
131 
132         protected override void OnClick(EventArgs e)
133         {
134             base.OnClick(e);
135             if (CheckState)
136             {
137                 isMouseDown = true;
138                 if (exclusion)
139                 {
140                     if (this.Parent != null)
141                     {
142 
143                         int ctlCount = this.Parent.Controls.Count;
144                         for (int i = 0; i < ctlCount; i++)
145                         {
146                             object o = this.Parent.Controls[i];
147                             if (o.GetType() == this.GetType())
148                             {
149                                 OurButton button = this.Parent.Controls[i] as OurButton;
150                                 if (button != null)
151                                 {
152                                     if (button != this)
153                                     {
154                                         button.PopUp();
155                                     }
156                                 }
157                             }
158                         }
159                     }
160                 }
161             }
162         }
163 
164         private void PopUp()
165         {
166             this.isMouseDown = false;
167             this.Invalidate();
168         }
169 
170         public override bool AutoSize
171         {
172             get
173             {
174                 return false;
175             }
176             set
177             {
178                 base.AutoSize = value;
179             }
180         }
181 
182         protected override void OnPaint(PaintEventArgs e)
183         {
184             Graphics g = e.Graphics;
185             g.SmoothingMode = SmoothingMode.HighQuality;
186             float imagex = 0;
187             float imagey = 0;
188             float tx = 0; float ty = 0;
189             float txtHeight = 0;
190             float txtWidth = 0;
191 
192             #region 绘制背景
193 
194             if (isMouseIn || isMouseDown )
195             {
196                 Color c = colorMouseIn;
197                 if (isMouseDown)
198                 {
199                     c = colorMouseDown;
200                 }
201                 int arrowHeight = 7;
202                 if (!withArrow)
203                     arrowHeight = 0;
204                 Rectangle rect = new Rectangle(0, 0, this.Width, this.Height - arrowHeight );
205                 Rectangle rect2 = new Rectangle(0, 0, this.Width - 1, this.Height - arrowHeight);
206 
207                 GraphicsPath path1 = null;
208                 GraphicsPath path2 = null;
209                 if (roundCorner)
210                 {
211                     if (withArrow)
212                     {
213                         path1 = GetRoundRectangleWithArrow(rect, 10);
214                         path2 = GetRoundRectangleWithArrow(rect2, 10);
215                     }
216                     else
217                     {
218                         path1 = GetRoundRectangle(rect, 10);
219                         path2 = GetRoundRectangle(rect2, 10);
220                     }
221                     g.FillPath(new SolidBrush(c), path1);
222                     if (withBorder)
223                         g.DrawPath(new Pen(Color.Silver, 2), path2);
224                 }
225                 else
226                 {
227                     g.FillRectangle(new SolidBrush(c), rect);
228                     g.DrawRectangle(new Pen(c, 2), rect2);
229                 }
230             }
231 
232             #endregion
233 
234             #region 绘制文本
235 
236             if (this.Text != string.Empty)
237             {
238                 SizeF sizeoftext = g.MeasureString(this.Text, Font);
239                 txtHeight = (float)(sizeoftext.Height);
240                 txtWidth = (float)(sizeoftext.Width);
241                 switch (TextPosition)
242                 {
243                     case eTextPosition.Top:
244                         tx = (float)((this.Width - sizeoftext.Width) / 2.0);
245                         ty = intervalBetweenTextAndBorder;
246                         break;
247                     case eTextPosition.Left:
248                         ty = (float)((this.Height - sizeoftext.Height) / 2.0);
249                         tx = intervalBetweenTextAndBorder;
250                         break;
251                     case eTextPosition.Right:
252                         if (Image == null)
253                             tx = this.Width - sizeoftext.Width - intervalBetweenTextAndBorder;
254                         else
255                             tx = intervalBetweenTextAndBorder + Image.Width + intervalBetweenTextAndImage;
256                         ty = (float)((this.Height - sizeoftext.Height) / 2.0);
257                         break;
258                     case eTextPosition.Bottom:
259                         if (Image != null)
260                             ty = intervalBetweenTextAndBorder + intervalBetweenTextAndImage + Image.Height;
261                         else
262                             ty = IntervalBetweenTextAndBorder;
263                         tx = (float)((this.Width - txtWidth) / 2.0);
264                         break;
265                 }
266                 g.DrawString(this.Text, Font, new SolidBrush(ForeColor), tx, ty);
267 
268             }
269 
270             #endregion
271 
272             #region 绘制图片
273 
274             if (Image != null)
275             {
276                 switch (TextPosition)
277                 {
278                     case eTextPosition.Top:
279                         imagex = (float)((this.Width - Image.Width) / 2.0);
280                         imagey = ty + txtHeight + intervalBetweenTextAndImage;
281                         break;
282                     case eTextPosition.Left:
283                         imagex = tx + txtWidth + intervalBetweenTextAndImage;
284                         imagey = (float)((this.Height - Image.Height) / 2.0);
285                         break;
286                     case eTextPosition.Right:
287                         imagex = IntervalBetweenTextAndBorder;
288                         imagey = (float)((this.Height - Image.Height) / 2.0);
289                         break;
290                     case eTextPosition.Bottom:
291                         imagey = intervalBetweenTextAndBorder;
292                         imagex = (float)((this.Width - Image.Width) / 2.0);
293                         break;
294                 }
295                 g.DrawImage(Image, imagex, imagey);
296             }
297 
298             #endregion
299 
300         }
301 
302         protected override void OnMouseEnter(EventArgs e)
303         {
304             base.OnMouseEnter(e);
305             isMouseIn = true;
306             this.Invalidate();
307         }
308 
309         protected override void OnMouseLeave(EventArgs e)
310         {
311             base.OnMouseLeave(e);
312             isMouseIn = false;
313             this.Invalidate();
314         }
315 
316         private GraphicsPath GetRoundRectangle(Rectangle rectangle, int r)
317         {
318             int l = 2 * r;
319             // 把圆角矩形分成八段直线、弧的组合,依次加到路径中  
320             GraphicsPath gp = new GraphicsPath();
321             gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
322             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);
323 
324             gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
325             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);
326 
327             gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
328             gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);
329 
330             gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
331             gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
332             return gp;
333         }
334 
335         private GraphicsPath GetRoundRectangleWithArrow(Rectangle rectangle, int r)
336         {
337             int l = 2 * r;
338             // 把圆角矩形分成八段直线、弧的组合,依次加到路径中  
339             GraphicsPath gp = new GraphicsPath();
340             gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
341             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);
342 
343             gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
344             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);
345 
346 
347             int miniwidth = 5;
348             int miniheight = 6;
349             //这是下面的一条线,把它分成四份
350             //            gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), );
351             //1
352             gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.Width / 2 + miniwidth, rectangle.Bottom));
353             //2
354             gp.AddLine(new Point(rectangle.Width / 2 + miniwidth, rectangle.Bottom), new Point(rectangle.Width / 2, rectangle.Bottom + miniheight));
355             //3
356             gp.AddLine(new Point(rectangle.Width / 2, rectangle.Bottom + miniheight), new Point(rectangle.Width / 2 - miniwidth, rectangle.Bottom));
357 
358             //4
359             gp.AddLine(new Point(rectangle.Width / 2 - miniwidth, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
360 
361             gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);
362 
363             gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
364             gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
365             return gp;
366         }
367 
368     }
369 
370     public enum eTextPosition
371     {
372         Top,
373         Left,
374         Right,
375         Bottom,
376     }
377 
378 }

下面是按钮的效果:

posted on 2013-03-23 12:10  CRH  阅读(260)  评论(1编辑  收藏  举报