C# 自定义箭头组件

C#自定义箭头组件,效果如图:

实现的功能:

    1) 箭头方向属性左、右、上、下;

    2) 颜色渐变,且颜色任意调整;

    3) 箭头大小位置任意调整;

    4) 其他。

主要代码如下:

  1 using System;
  2 using System.Collections;
  3 using System.ComponentModel;
  4 using System.Drawing;
  5 using System.Drawing.Drawing2D;
  6 using System.Data;
  7 using System.Windows.Forms;
  8 using System.ComponentModel.Design;
  9 
 10 namespace TestControls
 11 {
 12     #region enum
 13     /// <summary>
 14     /// 颜色填充方向
 15     /// </summary>
 16     public enum LinearGradientDirection
 17     {
 18         Vertical,
 19         Horizontal
 20     }
 21 
 22     /// <summary>
 23     /// 箭头方向
 24     /// </summary>
 25     public enum ArrowStyleType
 26     {
 27         None,
 28         Left,
 29         Right,
 30         Top,
 31         Bottom,
 32         LeftRight,
 33         TopBottom,
 34         UpBow,
 35         DownBow,
 36         LeftBow,
 37         RightBow,
 38     }
 39     #endregion
 40 
 41     public partial class ArrowLine : System.Windows.Forms.Control
 42     {
 43         #region 变量
 44         //private System.ComponentModel.Container components = null;
 45         private PointF[] m_pnts = null;                              // 箭头点坐标
 46         GraphicsPath m_gp = new GraphicsPath();                      // 绘制路径
 47         private Color m_ColorS = Color.WhiteSmoke;                  // 起始渐变色
 48         private Color m_ColorE = Color.DarkGray;
 49         private Color m_NormalStartColor = Color.WhiteSmoke;      // 常规起始渐变色
 50         private Color m_NormalEndColor = Color.DarkGray;
 51         private LinearGradientDirection m_lgdirect = LinearGradientDirection.Horizontal;
 52         private ArrowStyleType m_ArrowType = ArrowStyleType.None; // 箭头类型
 53         private float m_ArrowLength = 8.0f;                       // 箭标长度
 54         private float m_ArrowBodyWidth = 8.0f;                    // 箭身宽度
 55 
 56         private float m_BowHeight = 4.0f;                         // 弓长度
 57         private float m_BowWidth = 4.0f;                          // 弓宽度
 58         private bool m_antiAlias = false;                         // 反走样绘制
 59 
 60         private bool m_FrameEnabled = false;
 61         private int m_pCount = 8;
 62 
 63         private const int MINSIZE = 2;                        // 最小大小
 64         #endregion
 65 
 66         #region 属性
 67         /// <summary>
 68         /// 开始渐变颜色
 69         /// </summary>
 70         public Color NormalStartColor
 71         {
 72             get { return m_NormalStartColor; }
 73             set { m_NormalStartColor = value; Refresh(); }
 74         }
 75 
 76         /// <summary>
 77         ///结束渐变颜色
 78         /// </summary>
 79         public Color NormalEndColor
 80         {
 81             get { return m_NormalEndColor; }
 82             set { m_NormalEndColor = value; Refresh(); }
 83         }
 84 
 85         /// <summary>
 86         /// 渐变色方向
 87         /// </summary>
 88         public LinearGradientDirection ColorLinearDirection
 89         {
 90             get { return m_lgdirect; }
 91             set { m_lgdirect = value; Refresh(); }
 92         }
 93 
 94 
 95         /// <summary>
 96         /// 是否有立体框架
 97         /// </summary>
 98         public bool FrameEnabled
 99         {
100             get { return m_FrameEnabled; }
101             set { m_FrameEnabled = value; Refresh(); }
102         }
103 
104         /// <summary>
105         /// 箭头类型
106         /// </summary>
107         public ArrowStyleType ArrowStyle
108         {
109             get { return m_ArrowType; }
110             set
111             {
112                 m_ArrowType = value;
113                 Clear();
114                 Init();
115                 Refresh();
116             }
117         }
118 
119         /// <summary>
120         /// 箭标长度
121         /// </summary>
122         public float ArrowLength
123         {
124             get { return m_ArrowLength; }
125             set
126             {
127                 m_ArrowLength = value;
128                 // AdjustmentBodyWH();
129                 Clear();
130                 Init();
131                 Refresh();
132             }
133         }
134 
135         /// <summary>
136         /// 箭身宽度
137         /// </summary>
138         public float ArrowBodyWidth
139         {
140             get { return m_ArrowBodyWidth; }
141             set
142             {
143                 m_ArrowBodyWidth = value;
144                 //AdjustmentBodyWH();
145                 Clear();
146                 Init();
147                 Refresh();
148             }
149         }
150 
151         /// <summary>
152         /// 弓长度
153         /// </summary>
154         public float BowHeight
155         {
156             get { return m_BowHeight; }
157             set
158             {
159                 m_BowHeight = value;
160                 Clear();
161                 Init();
162                 Refresh();
163             }
164         }
165 
166         /// <summary>
167         /// 弓宽度
168         /// </summary>
169         public float BowWidth
170         {
171             get { return m_BowWidth; }
172             set
173             {
174                 m_BowWidth = value;
175                 Clear();
176                 Init();
177                 Refresh();
178             }
179         }
180 
181         /// <summary>
182         /// 反走样
183         /// </summary>
184         public bool AntiAlias
185         {
186             get { return m_antiAlias; }
187             set
188             {
189                 m_antiAlias = value;
190                 Clear();
191                 Init();
192                 Refresh();
193             }
194         }
195 
196         private bool m_LinearGradientUsingClient = true;  //渐变色使用客户区
197         /// <summary>
198         /// 渐变色使用是否只使用控件客户区
199         /// </summary>
200         public bool LinearGradientUsingClient
201         {
202             get { return m_LinearGradientUsingClient; }
203             set
204             {
205 
206                 m_LinearGradientUsingClient = value;
207                 {
208                     Clear();
209                     Init();
210                     Refresh();
211                 }
212             }
213         }
214 
215         private Rectangle m_LinearGradientRect;
216         /// <summary>
217         /// 渐变色使用区区域范围
218         /// </summary>
219         public Rectangle LinearGradientRect
220         {
221             get { return m_LinearGradientRect; }
222             set
223             {
224 
225                 m_LinearGradientRect = value;
226                 {
227                     Clear();
228                     Init();
229                     Refresh();
230                 }
231             }
232         }
233         #endregion
234 
235         #region 构造函数
236         public ArrowLine()
237         {
238             InitializeComponent();
239             Init();
240 
241             SetStyle(ControlStyles.UserPaint, true);
242             SetStyle(ControlStyles.ResizeRedraw, true);
243             SetStyle(ControlStyles.DoubleBuffer, true);
244             SetStyle(ControlStyles.UserPaint, true);
245             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
246             SetStyle(ControlStyles.UserPaint, true);
247             SetStyle(ControlStyles.SupportsTransparentBackColor, true);
248             this.BackColor = Color.Transparent;
249 
250             m_LinearGradientRect = this.ClientRectangle;
251         }
252 
253         public ArrowLine(IContainer container)
254         {
255             container.Add(this);
256             InitializeComponent();
257         }
258         #endregion
259 
260         #region 继承函数
261 
262         /// <summary>
263         /// Resize
264         /// </summary>
265         /// <param name="e"></param>
266         protected override void OnResize(EventArgs e)
267         {
268             Clear();
269             Init();
270             Refresh();
271         }
272 
273         /// <summary>
274         /// Paint
275         /// </summary>
276         /// <param name="e"></param>
277         protected override void OnPaint(PaintEventArgs e)
278         {
279             m_ColorS = NormalStartColor;
280             m_ColorE = NormalEndColor;
281 
282             Rectangle rect = this.ClientRectangle;
283             if (m_LinearGradientUsingClient)
284             {
285                 rect = this.ClientRectangle;
286             }
287             else
288             {
289                 rect = this.RectangleToClient(m_LinearGradientRect);
290             }
291 
292 
293             LinearGradientBrush b = null;
294             if (ColorLinearDirection == LinearGradientDirection.Horizontal)
295             {
296                 b = new LinearGradientBrush(rect, m_ColorS, m_ColorE, 0, false);
297             }
298             else
299             {
300                 b = new LinearGradientBrush(rect, m_ColorS, m_ColorE, 90, false);
301             }
302 
303             // 设计模式
304             if (this.DesignMode != true)
305             {
306                 e.Graphics.SetClip(m_gp);
307             }
308 
309             //反走样
310             if (m_antiAlias)
311             {
312                 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
313             }
314             else
315             {
316                 e.Graphics.SmoothingMode = SmoothingMode.None;
317             }
318 
319             e.Graphics.FillPath(b, m_gp);  //填充路径
320             b.Dispose();
321 
322             //划框
323             if (m_FrameEnabled)
324             {
325                 ColorArrowFrame(e);
326             }
327         }
328 
329         #endregion
330 
331         #region 方法
332 
333         private void Clear()
334         {
335             m_pnts = null;
336             m_gp.Reset();
337         }
338 
339         private void ColorArrowFrame(PaintEventArgs e)
340         {
341             Pen p1 = null;
342             {
343                 if (this.Width < this.Height)
344                 {
345                     for (int i = 0; i < m_pCount - 1; i++)
346                     {
347                         if (m_pnts[i].Y <= m_pnts[i + 1].Y)
348                         {
349                             p1 = new Pen(SystemColors.ControlLightLight, 1f);
350                         }
351                         else
352                         {
353                             p1 = new Pen(SystemColors.ControlDark, 1f);
354                         }
355                         e.Graphics.DrawLine(p1, m_pnts[i].X, m_pnts[i].Y, m_pnts[i + 1].X, m_pnts[i + 1].Y);
356                     }
357                 }
358                 else
359                 {
360                     for (int i = 0; i < m_pCount - 1; i++)
361                     {
362                         if (m_pnts[i].Y > m_pnts[i + 1].Y)
363                         {
364                             p1 = new Pen(SystemColors.ControlLightLight, 1f);
365                         }
366                         else
367                         {
368                             p1 = new Pen(SystemColors.ControlDark, 1f);
369                         }
370                         e.Graphics.DrawLine(p1, m_pnts[i].X, m_pnts[i].Y, m_pnts[i + 1].X, m_pnts[i + 1].Y);
371                     }
372                 }
373             }
374 
375         }
376 
377         /// <summary>
378         /// Sequence to create the button
379         /// </summary>
380         private void Init()
381         {
382             MakeSquare();
383 
384             float dx = this.Width - 2;
385             float dy = this.Height - 2;
386 
387             if (m_FrameEnabled == false)
388             {
389                 dx = this.Width;
390                 dy = this.Height;
391             }
392 
393             // 产生箭头坐标
394             BuildInitialArrow();
395 
396             // 绘制
397             GraphicsPathFromPoints(m_pnts, m_gp);
398 
399         }
400 
401         private void MakeSquare()
402         {
403             this.SuspendLayout();
404             if (this.Width < MINSIZE)
405             {
406                 this.Size = new Size(MINSIZE, MINSIZE);
407             }
408             else
409             {
410                 //if ( this.Size.Width < this.Size.Height )
411                 //{
412                 //    this.Size = new Size ( this.Size.Width, this.Size.Width );
413                 //}
414                 //else
415                 //{
416                 //    this.Size = new Size ( this.Size.Height, this.Size.Height );
417                 //}
418             }
419             this.ResumeLayout();
420         }
421 
422         /// <summary>
423         /// 创建箭头点
424         /// </summary>
425         private void BuildInitialArrow()
426         {
427             // AdjustmentBodyWH();
428 
429             float dx = this.Width - 2;
430             float dy = this.Height - 2;
431 
432             if (m_FrameEnabled == false)
433             {
434                 dx = this.Width;
435                 dy = this.Height;
436             }
437 
438             switch (m_ArrowType)
439             {
440                 case ArrowStyleType.None:
441                     m_pCount = 5;
442                     m_pnts = new PointF[m_pCount];
443 
444                     m_pnts[0] = new PointF(0, 0);
445                     m_pnts[1] = new PointF(dx, 0);
446                     m_pnts[2] = new PointF(dx, dy);
447                     m_pnts[3] = new PointF(0, dy);
448                     m_pnts[4] = new PointF(0, 0);
449                     break;
450                 case ArrowStyleType.Top:
451                     m_pCount = 8;
452                     m_pnts = new PointF[m_pCount];
453 
454                     m_pnts[0] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy);
455                     m_pnts[1] = new PointF((dx - m_ArrowBodyWidth) / 2f, m_ArrowLength);
456                     m_pnts[2] = new PointF(0, m_ArrowLength);
457                     m_pnts[3] = new PointF(dx / 2f, 0);
458                     m_pnts[4] = new PointF(dx, m_ArrowLength);
459                     m_pnts[5] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, m_ArrowLength);
460                     m_pnts[6] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy);
461                     m_pnts[7] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy);
462                     break;
463                 case ArrowStyleType.Left:
464                     m_pCount = 8;
465                     m_pnts = new PointF[m_pCount];
466                     m_pnts[0] = new PointF(dx, dy / 2f - m_ArrowBodyWidth / 2f);
467                     m_pnts[1] = new PointF(m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
468                     m_pnts[2] = new PointF(m_ArrowLength, 0);
469                     m_pnts[3] = new PointF(0, dy / 2f);
470                     m_pnts[4] = new PointF(m_ArrowLength, dy);
471                     m_pnts[5] = new PointF(m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
472                     m_pnts[6] = new PointF(dx, dy / 2f + m_ArrowBodyWidth / 2f);
473                     m_pnts[7] = new PointF(dx, dy / 2f - m_ArrowBodyWidth / 2f);
474                     break;
475                 case ArrowStyleType.Right:
476                     m_pCount = 8;
477                     m_pnts = new PointF[m_pCount];
478                     m_pnts[0] = new PointF(0, dy / 2f - m_ArrowBodyWidth / 2f);
479                     m_pnts[1] = new PointF(dx - m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
480                     m_pnts[2] = new PointF(dx - m_ArrowLength, 0);
481                     m_pnts[3] = new PointF(dx, dy / 2f);
482                     m_pnts[4] = new PointF(dx - m_ArrowLength, dy);
483                     m_pnts[5] = new PointF(dx - m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
484                     m_pnts[6] = new PointF(0, dy / 2f + m_ArrowBodyWidth / 2f);
485                     m_pnts[7] = new PointF(0, dy / 2f - m_ArrowBodyWidth / 2f);
486                     break;
487                 case ArrowStyleType.Bottom:
488                     m_pCount = 8;
489                     m_pnts = new PointF[m_pCount];
490                     m_pnts[0] = new PointF((dx - m_ArrowBodyWidth) / 2f, 0);
491                     m_pnts[1] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy - m_ArrowLength);
492                     m_pnts[2] = new PointF(0, dy - m_ArrowLength);
493                     m_pnts[3] = new PointF(dx / 2f, dy);
494                     m_pnts[4] = new PointF(dx, dy - m_ArrowLength);
495                     m_pnts[5] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
496                     m_pnts[6] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, 0);
497                     m_pnts[7] = new PointF((dx - m_ArrowBodyWidth) / 2f, 0);
498                     break;
499                 case ArrowStyleType.LeftRight:
500                     m_pCount = 11;
501                     m_pnts = new PointF[m_pCount];
502                     m_pnts[0] = new PointF(0, dy / 2f);
503                     m_pnts[1] = new PointF(m_ArrowLength, 0);
504                     m_pnts[2] = new PointF(m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
505                     m_pnts[3] = new PointF(dx - m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
506                     m_pnts[4] = new PointF(dx - m_ArrowLength, 0);
507                     m_pnts[5] = new PointF(dx, dy / 2f);
508                     m_pnts[6] = new PointF(dx - m_ArrowLength, dy);
509                     m_pnts[7] = new PointF(dx - m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
510                     m_pnts[8] = new PointF(m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
511                     m_pnts[9] = new PointF(m_ArrowLength, dy);
512                     m_pnts[10] = new PointF(0, dy / 2f);
513                     break;
514                 case ArrowStyleType.TopBottom:
515                     m_pCount = 11;
516                     m_pnts = new PointF[m_pCount];
517                     m_pnts[0] = new PointF(dx / 2f, dy);
518                     m_pnts[1] = new PointF(0, dy - m_ArrowLength);
519                     m_pnts[2] = new PointF(dx / 2f - m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
520                     m_pnts[3] = new PointF(dx / 2f - m_ArrowBodyWidth / 2f, m_ArrowLength);
521                     m_pnts[4] = new PointF(0, m_ArrowLength);
522                     m_pnts[5] = new PointF(dx / 2f, 0);
523                     m_pnts[6] = new PointF(dx, m_ArrowLength);
524                     m_pnts[7] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, m_ArrowLength);
525                     m_pnts[8] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
526                     m_pnts[9] = new PointF(dx, dy - m_ArrowLength);
527                     m_pnts[10] = new PointF(dx / 2f, dy);
528                     break;
529                 case ArrowStyleType.UpBow:
530                     m_pCount = 9;
531                     m_pnts = new PointF[m_pCount];
532                     m_pnts[0] = new PointF(0, 0);
533                     m_pnts[1] = new PointF(0, dy);
534                     m_pnts[2] = new PointF(dx, dy);
535                     m_pnts[3] = new PointF(dx, 0);
536                     m_pnts[4] = new PointF(dx - m_BowWidth, 0);
537                     m_pnts[5] = new PointF(dx - m_BowWidth, dy - m_BowHeight);
538                     m_pnts[6] = new PointF(m_BowWidth, dy - m_BowHeight);
539                     m_pnts[7] = new PointF(m_BowWidth, 0);
540                     m_pnts[8] = new PointF(0, 0);
541                     break;
542                 case ArrowStyleType.DownBow:
543                     m_pCount = 9;
544                     m_pnts = new PointF[m_pCount];
545                     m_pnts[0] = new PointF(0, dy);
546                     m_pnts[1] = new PointF(0, 0);
547                     m_pnts[2] = new PointF(dx, 0);
548                     m_pnts[3] = new PointF(dx, dy);
549                     m_pnts[4] = new PointF(dx - m_BowWidth, dy);
550                     m_pnts[5] = new PointF(dx - m_BowWidth, m_BowHeight);
551                     m_pnts[6] = new PointF(m_BowWidth, m_BowHeight);
552                     m_pnts[7] = new PointF(m_BowWidth, dy);
553                     m_pnts[8] = new PointF(0, dy);
554                     break;
555                 case ArrowStyleType.LeftBow:
556                     m_pCount = 9;
557                     m_pnts = new PointF[m_pCount];
558                     m_pnts[0] = new PointF(0, 0);
559                     m_pnts[1] = new PointF(dx, 0);
560                     m_pnts[2] = new PointF(dx, dy);
561                     m_pnts[3] = new PointF(0, dy);
562                     m_pnts[4] = new PointF(0, dy - m_BowHeight);
563                     m_pnts[5] = new PointF(dx - m_BowWidth, dy - m_BowHeight);
564                     m_pnts[6] = new PointF(dx - m_BowWidth, m_BowHeight);
565                     m_pnts[7] = new PointF(0, m_BowHeight);
566                     m_pnts[8] = new PointF(0, 0);
567                     break;
568                 case ArrowStyleType.RightBow:
569                     m_pCount = 9;
570                     m_pnts = new PointF[m_pCount];
571                     m_pnts[0] = new PointF(0, 0);
572                     m_pnts[1] = new PointF(dx, 0);
573                     m_pnts[2] = new PointF(dx, m_BowHeight);
574                     m_pnts[3] = new PointF(m_BowWidth, m_BowHeight);
575                     m_pnts[4] = new PointF(m_BowWidth, dy - m_BowHeight);
576                     m_pnts[5] = new PointF(dx, dy - m_BowHeight);
577                     m_pnts[6] = new PointF(dx, dy);
578                     m_pnts[7] = new PointF(0, dy);
579                     m_pnts[8] = new PointF(0, 0);
580                     break;
581 
582                 default:
583                     break;
584             }
585         }
586 
587 
588         private void GraphicsPathFromPoints(PointF[] pnts, GraphicsPath gp)
589         {
590             for (int i = 0; i < pnts.Length - 1; i++)
591             {
592                 gp.AddLine(pnts[i].X, pnts[i].Y, pnts[i + 1].X, pnts[i + 1].Y);
593             }
594         }
595 
596         //protected override void PostFilterProperties(IDictionary Properties)
597         //{
598         //    Properties.Remove("AllowDrop");
599         //    Properties.Remove("BackColor");
600         //    Properties.Remove("BackgroundImage");
601         //    Properties.Remove("ContextMenu");
602         //    Properties.Remove("FlatStyle");
603         //    Properties.Remove("Image");
604         //    Properties.Remove("ImageAlign");
605         //    Properties.Remove("ImageIndex");
606         //    Properties.Remove("ImageList");
607         //    Properties.Remove("TextAlign");
608         //    Properties.Remove("Text");
609         //    Properties.Remove("Enabled");
610         //}
611         #endregion
612     }
613 }

测试程序代码下载地址:http://pan.baidu.com/share/link?shareid=326955656&uk=1126205289

原文地址:https://www.cnblogs.com/Jins/p/3122781.html