戏说 .NET GDI+系列学习教程(三、Graphics类的应用_自定义控件--主要用于画面拖拽效果)

如题,需求:在某个图片上用户可以手动指定位置。

如下:

中心思想:仿照Visual Studio工具中的控件的做法

如何仿照呢?

1.自定义的控件类继承System.Windows.Forms.Control

1.1.通过Graphics对象,绘制出我们想要的形状

  1 #region enum
  2     /// <summary>
  3     /// 渐变颜色填充方向
  4     /// </summary>
  5     public enum LinearGradientDirection
  6     {
  7         /// <summary>
  8         /// 垂直方向
  9         /// </summary>
 10         Vertical,
 11         /// <summary>
 12         /// 水平方向
 13         /// </summary>
 14         Horizontal
 15     }
 16 
 17     /// <summary>
 18     /// 箭头方向
 19     /// </summary>
 20     public enum ArrowStyleType
 21     {
 22         /// <summary>
 23         /// 没有箭头 
 24         /// </summary>
 25         None,
 26         /// <summary>
 27         /// 左箭头(⬅)
 28         /// </summary>
 29         Left,
 30         /// <summary>
 31         /// 右箭头(➡)
 32         /// </summary>
 33         Right,
 34         /// <summary>
 35         /// 上箭头(↑)
 36         /// </summary>
 37         Top,
 38         /// <summary>
 39         /// 下箭头(⬇)
 40         /// </summary>
 41         Bottom,
 42         /// <summary>
 43         /// 左右箭头(↔)
 44         /// </summary>
 45         LeftRight,
 46         /// <summary>
 47         /// 上下箭头(↕)
 48         /// </summary>
 49         TopBottom,
 50         /// <summary>
 51         /// 上弓
 52         /// </summary>
 53         UpBow,
 54         /// <summary>
 55         /// 下弓
 56         /// </summary>
 57         DownBow,
 58         /// <summary>
 59         /// 左弓
 60         /// </summary>
 61         LeftBow,
 62         /// <summary>
 63         /// 右弓
 64         /// </summary>
 65         RightBow,
 66     }
 67     #endregion
 68 
 69     class ArrowControll : System.Windows.Forms.Control
 70     {
 71         #region 变量
 72         private PointF[] m_pnts = null;                              // 箭头点坐标
 73         GraphicsPath m_gp = new GraphicsPath();                      // 绘制路径
 74         private Color m_ColorS = Color.WhiteSmoke;                  // 起始渐变色
 75         private Color m_ColorE = Color.DarkGray;
 76         private Color m_NormalStartColor = Color.WhiteSmoke;      // 常规起始渐变色
 77         private Color m_NormalEndColor = Color.DarkGray;
 78         private LinearGradientDirection m_lgdirect = LinearGradientDirection.Horizontal;
 79         private ArrowStyleType m_ArrowType = ArrowStyleType.UpBow; // 箭头类型
 80         private float m_ArrowLength = 8.0f;                       // 箭标长度
 81         private float m_ArrowBodyWidth = 8.0f;                    // 箭身宽度
 82 
 83         private float m_BowHeight = 4.0f;                         // 弓长度
 84         private float m_BowWidth = 4.0f;                          // 弓宽度
 85         private bool m_antiAlias = false;                         // 反走样绘制
 86 
 87         private bool m_FrameEnabled = false;
 88         private int m_pCount = 8;
 89 
 90         private const int MINSIZE = 2;                        // 最小大小
 91         #endregion
 92 
 93         #region 属性
 94         /// <summary>
 95         /// 开始渐变颜色
 96         /// </summary>
 97         public Color NormalStartColor
 98         {
 99             get { return m_NormalStartColor; }
100             set { m_NormalStartColor = value; Refresh(); }
101         }
102 
103         /// <summary>
104         ///结束渐变颜色
105         /// </summary>
106         public Color NormalEndColor
107         {
108             get { return m_NormalEndColor; }
109             set { m_NormalEndColor = value; Refresh(); }
110         }
111 
112         /// <summary>
113         /// 渐变色方向
114         /// </summary>
115         public LinearGradientDirection ColorLinearDirection
116         {
117             get { return m_lgdirect; }
118             set { m_lgdirect = value; Refresh(); }
119         }
120 
121         /// <summary>
122         /// 是否有立体框架
123         /// </summary>
124         public bool FrameEnabled
125         {
126             get { return m_FrameEnabled; }
127             set { m_FrameEnabled = value; Refresh(); }
128         }
129 
130         /// <summary>
131         /// 箭头类型
132         /// </summary>
133         public ArrowStyleType ArrowStyle
134         {
135             get { return m_ArrowType; }
136             set
137             {
138                 m_ArrowType = value;
139                 Clear();
140                 Init();
141                 Refresh();
142             }
143         }
144 
145         /// <summary>
146         /// 箭标长度
147         /// </summary>
148         public float ArrowLength
149         {
150             get { return m_ArrowLength; }
151             set
152             {
153                 m_ArrowLength = value;
154                 // AdjustmentBodyWH();
155                 Clear();
156                 Init();
157                 Refresh();
158             }
159         }
160 
161         /// <summary>
162         /// 箭身宽度
163         /// </summary>
164         public float ArrowBodyWidth
165         {
166             get { return m_ArrowBodyWidth; }
167             set
168             {
169                 m_ArrowBodyWidth = value;
170                 Clear();
171                 Init();
172                 Refresh();
173             }
174         }
175 
176         /// <summary>
177         /// 弓长度
178         /// </summary>
179         public float BowHeight
180         {
181             get { return m_BowHeight; }
182             set
183             {
184                 m_BowHeight = value;
185                 Clear();
186                 Init();
187                 Refresh();
188             }
189         }
190 
191         /// <summary>
192         /// 弓宽度
193         /// </summary>
194         public float BowWidth
195         {
196             get { return m_BowWidth; }
197             set
198             {
199                 m_BowWidth = value;
200                 Clear();
201                 Init();
202                 Refresh();
203             }
204         }
205 
206         /// <summary>
207         /// 反走样
208         /// </summary>
209         public bool AntiAlias
210         {
211             get { return m_antiAlias; }
212             set
213             {
214                 m_antiAlias = value;
215                 Clear();
216                 Init();
217                 Refresh();
218             }
219         }
220 
221         private bool m_LinearGradientUsingClient = true;  //渐变色使用控件区域
222         /// <summary>
223         /// 渐变色使用是否只使用控件区域
224         /// </summary>
225         public bool LinearGradientUsingClient
226         {
227             get { return m_LinearGradientUsingClient; }
228             set
229             {
230                 m_LinearGradientUsingClient = value;
231                 {
232                     Clear();
233                     Init();
234                     Refresh();
235                 }
236             }
237         }
238 
239         private Rectangle m_LinearGradientRect;
240         /// <summary>
241         /// 渐变色使用区域范围
242         /// </summary>
243         public Rectangle LinearGradientRect
244         {
245             get { return m_LinearGradientRect; }
246             set
247             {
248                 m_LinearGradientRect = value;
249                 {
250                     Clear();
251                     Init();
252                     Refresh();
253                 }
254             }
255         }
256         #endregion
257 
258         #region 01构造函数 -- 箭头路径GraphicsPath m_gp = new GraphicsPath();    
259         /// <summary>
260         /// 通过构造函数
261         /// 绘制箭头路径
262         /// 初期化
263         /// </summary>
264         public ArrowControll()
265         {
266             InitializeComponent();
267             Init();
268 
269             //在缓冲区中进行绘制,并且完成后将结果输出到屏幕。
270             //双缓冲可以防止因重绘控件而引起的闪烁。
271             //如果将 DoubleBuffer 设置为 true,则还应将 UserPaint 和 AllPaintingInWmPaint 设置为 true
272             SetStyle(ControlStyles.DoubleBuffer, true);
273 
274             //控件忽略窗口消息 WM_ERASEBKGND 以减少闪烁。 
275             //仅当将 UserPaint 位设置为 true 时,才应用此样式
276             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
277 
278             //如果为 true,则会由控件而不是由操作系统来绘制控件自身。 
279             //如果 false,则不会引发 Paint 事件。 
280             //此样式仅适用于从 Control 派生的类
281             SetStyle(ControlStyles.UserPaint, true);
282 
283             //控件会在调整大小时进行重绘
284             SetStyle(ControlStyles.ResizeRedraw, true);
285 
286             //如果为 true,则控件接受 alpha 组件数小于 255 个的 BackColor 来模拟透明度。 
287             //仅当将 UserPaint 位设置为 true 且父控件从 Control 派生时,才会模拟透明度。
288             SetStyle(ControlStyles.SupportsTransparentBackColor, true);
289             this.BackColor = Color.Transparent;
290 
291             m_LinearGradientRect = this.ClientRectangle;
292         }
293         #endregion
294 
295         #region 02继承函数 -- 通过控件OnPaint方法把构造函数所箭头路径绘制出来(e.Graphics.FillPath(b, m_gp);)
296 
297         /// <summary>
298         /// 控件Size改变时,触发OnResize方法
299         /// </summary>
300         /// <param name="e"></param>
301         protected override void OnResize(EventArgs e)
302         {
303             Clear();
304             Init();
305             Refresh();
306         }
307 
308         /// <summary>
309         /// 控件重绘时,触发OnPaint方法
310         /// </summary>
311         /// <param name="e"></param>
312         protected override void OnPaint(PaintEventArgs e)
313         {
314             //开始颜色
315             m_ColorS = NormalStartColor;
316             //结束颜色
317             m_ColorE = NormalEndColor;
318 
319             //设置渐变区域Rectangle
320             Rectangle rect = this.ClientRectangle;
321             if (m_LinearGradientUsingClient)
322             {
323                 rect = this.ClientRectangle;
324             }
325             else
326             {
327                 rect = this.RectangleToClient(m_LinearGradientRect);
328             }
329 
330             //使用线性渐变绘制区域
331             LinearGradientBrush b = null;
332             if (ColorLinearDirection == LinearGradientDirection.Horizontal)
333             {
334                 b = new LinearGradientBrush(rect, m_ColorS, m_ColorE, 0, false);
335             }
336             else
337             {
338                 b = new LinearGradientBrush(rect, m_ColorS, m_ColorE, 90, false);
339             }
340 
341             // 设计模式
342             if (this.DesignMode != true)
343             {
344                 //setClip方法的原理是通过只在屏幕上显示一部分内容,让图片恰好位于该部分的内容显示出来。
345                 //把e.Graphics 的区域大小设置为绘画区域一致,
346                 e.Graphics.SetClip(m_gp);
347             }
348 
349             //SmoothingModeAntiAlias    指定消除锯齿的呈现。
350             //SmoothingModeDefault      指定默认模式。
351             //SmoothingModeHighQuality  指定高质量、低速度呈现。
352             //SmoothingModeHighSpeed    指定高速度、低质量呈现。
353             //SmoothingModeInvalid      指定一个无效模式。
354             //SmoothingModeNone         指定不消除锯齿。
355             //反走样
356             if (m_antiAlias)
357             {
358                 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
359             }
360             else
361             {
362                 e.Graphics.SmoothingMode = SmoothingMode.None;
363             }
364 
365             e.Graphics.FillPath(b, m_gp);  //填充路径
366             b.Dispose();
367 
368             //划框
369             if (m_FrameEnabled)
370             {
371                 ColorArrowFrame(e);
372             }
373         }
374 
375         #endregion
376 
377         #region 方法 -- 设置控件形状:1.坐标 2.绘制路径
378 
379         private void Clear()
380         {
381             // 清除箭头坐标数组
382             m_pnts = null;
383             // 清空 PathPoints 和 PathTypes 数组并将 FillMode 设置为 Alternate。
384             m_gp.Reset();
385         }
386 
387         /// <summary>
388         /// 箭头框架
389         /// </summary>
390         /// <param name="e"></param>
391         private void ColorArrowFrame(PaintEventArgs e)
392         {
393             Pen p1 = null;
394             {
395                 if (this.Width < this.Height)
396                 {
397                     for (int i = 0; i < m_pCount - 1; i++)
398                     {
399                         if (m_pnts[i].Y <= m_pnts[i + 1].Y)
400                         {
401                             p1 = new Pen(SystemColors.ControlLightLight, 1f);
402                         }
403                         else
404                         {
405                             p1 = new Pen(SystemColors.ControlDark, 1f);
406                         }
407                         e.Graphics.DrawLine(p1, m_pnts[i].X, m_pnts[i].Y, m_pnts[i + 1].X, m_pnts[i + 1].Y);
408                     }
409                 }
410                 else
411                 {
412                     for (int i = 0; i < m_pCount - 1; i++)
413                     {
414                         if (m_pnts[i].Y > m_pnts[i + 1].Y)
415                         {
416                             p1 = new Pen(SystemColors.ControlLightLight, 1f);
417                         }
418                         else
419                         {
420                             p1 = new Pen(SystemColors.ControlDark, 1f);
421                         }
422                         e.Graphics.DrawLine(p1, m_pnts[i].X, m_pnts[i].Y, m_pnts[i + 1].X, m_pnts[i + 1].Y);
423                     }
424                 }
425             }
426         }
427 
428         /// <summary>
429         /// 初期化
430         /// 1.定义箭头坐标
431         /// 2.根据箭头坐标设置绘制路径
432         /// </summary>
433         private void Init()
434         {
435             //MakeSquare();
436 
437             // 产生箭头坐标
438             BuildInitialArrow();
439 
440             // 绘制路径
441             GraphicsPathFromPoints(m_pnts, m_gp);
442         }
443 
444         //private void MakeSquare()
445         //{
446         //    this.SuspendLayout();
447         //    if (this.Width < MINSIZE)
448         //    {
449         //        this.Size = new Size(MINSIZE, MINSIZE);
450         //    }
451         //    else
452         //    {
453         //        if (this.Size.Width < this.Size.Height)
454         //        {
455         //            this.Size = new Size(this.Size.Width, this.Size.Width);
456         //        }
457         //        else
458         //        {
459         //            this.Size = new Size(this.Size.Height, this.Size.Height);
460         //        }
461         //    }
462         //    this.ResumeLayout();
463         //}
464 
465         /// <summary>
466         /// 创建箭头坐标组
467         /// </summary>
468         private void BuildInitialArrow()
469         {
470             float dx = this.Width - 2;
471             float dy = this.Height - 2;
472 
473             if (m_FrameEnabled == false)
474             {
475                 dx = this.Width;
476                 dy = this.Height;
477             }
478 
479             switch (m_ArrowType)
480             {
481                 case ArrowStyleType.None:
482                     m_pCount = 5;
483                     m_pnts = new PointF[m_pCount];
484 
485                     m_pnts[0] = new PointF(0, 0);
486                     m_pnts[1] = new PointF(dx, 0);
487                     m_pnts[2] = new PointF(dx, dy);
488                     m_pnts[3] = new PointF(0, dy);
489                     m_pnts[4] = new PointF(0, 0);
490                     break;
491                 case ArrowStyleType.Top:
492                     m_pCount = 8;
493                     m_pnts = new PointF[m_pCount];
494 
495                     m_pnts[0] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy);
496                     m_pnts[1] = new PointF((dx - m_ArrowBodyWidth) / 2f, m_ArrowLength);
497                     m_pnts[2] = new PointF(0, m_ArrowLength);
498                     m_pnts[3] = new PointF(dx / 2f, 0);
499                     m_pnts[4] = new PointF(dx, m_ArrowLength);
500                     m_pnts[5] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, m_ArrowLength);
501                     m_pnts[6] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy);
502                     m_pnts[7] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy);
503                     break;
504                 case ArrowStyleType.Left:
505                     m_pCount = 8;
506                     m_pnts = new PointF[m_pCount];
507                     m_pnts[0] = new PointF(dx, dy / 2f - m_ArrowBodyWidth / 2f);
508                     m_pnts[1] = new PointF(m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
509                     m_pnts[2] = new PointF(m_ArrowLength, 0);
510                     m_pnts[3] = new PointF(0, dy / 2f);
511                     m_pnts[4] = new PointF(m_ArrowLength, dy);
512                     m_pnts[5] = new PointF(m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
513                     m_pnts[6] = new PointF(dx, dy / 2f + m_ArrowBodyWidth / 2f);
514                     m_pnts[7] = new PointF(dx, dy / 2f - m_ArrowBodyWidth / 2f);
515                     break;
516                 case ArrowStyleType.Right:
517                     m_pCount = 8;
518                     m_pnts = new PointF[m_pCount];
519                     m_pnts[0] = new PointF(0, dy / 2f - m_ArrowBodyWidth / 2f);
520                     m_pnts[1] = new PointF(dx - m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
521                     m_pnts[2] = new PointF(dx - m_ArrowLength, 0);
522                     m_pnts[3] = new PointF(dx, dy / 2f);
523                     m_pnts[4] = new PointF(dx - m_ArrowLength, dy);
524                     m_pnts[5] = new PointF(dx - m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
525                     m_pnts[6] = new PointF(0, dy / 2f + m_ArrowBodyWidth / 2f);
526                     m_pnts[7] = new PointF(0, dy / 2f - m_ArrowBodyWidth / 2f);
527                     break;
528                 case ArrowStyleType.Bottom:
529                     m_pCount = 8;
530                     m_pnts = new PointF[m_pCount];
531                     m_pnts[0] = new PointF((dx - m_ArrowBodyWidth) / 2f, 0);
532                     m_pnts[1] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy - m_ArrowLength);
533                     m_pnts[2] = new PointF(0, dy - m_ArrowLength);
534                     m_pnts[3] = new PointF(dx / 2f, dy);
535                     m_pnts[4] = new PointF(dx, dy - m_ArrowLength);
536                     m_pnts[5] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
537                     m_pnts[6] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, 0);
538                     m_pnts[7] = new PointF((dx - m_ArrowBodyWidth) / 2f, 0);
539                     break;
540                 case ArrowStyleType.LeftRight:
541                     m_pCount = 11;
542                     m_pnts = new PointF[m_pCount];
543                     m_pnts[0] = new PointF(0, dy / 2f);
544                     m_pnts[1] = new PointF(m_ArrowLength, 0);
545                     m_pnts[2] = new PointF(m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
546                     m_pnts[3] = new PointF(dx - m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
547                     m_pnts[4] = new PointF(dx - m_ArrowLength, 0);
548                     m_pnts[5] = new PointF(dx, dy / 2f);
549                     m_pnts[6] = new PointF(dx - m_ArrowLength, dy);
550                     m_pnts[7] = new PointF(dx - m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
551                     m_pnts[8] = new PointF(m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
552                     m_pnts[9] = new PointF(m_ArrowLength, dy);
553                     m_pnts[10] = new PointF(0, dy / 2f);
554                     break;
555                 case ArrowStyleType.TopBottom:
556                     m_pCount = 11;
557                     m_pnts = new PointF[m_pCount];
558                     m_pnts[0] = new PointF(dx / 2f, dy);
559                     m_pnts[1] = new PointF(0, dy - m_ArrowLength);
560                     m_pnts[2] = new PointF(dx / 2f - m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
561                     m_pnts[3] = new PointF(dx / 2f - m_ArrowBodyWidth / 2f, m_ArrowLength);
562                     m_pnts[4] = new PointF(0, m_ArrowLength);
563                     m_pnts[5] = new PointF(dx / 2f, 0);
564                     m_pnts[6] = new PointF(dx, m_ArrowLength);
565                     m_pnts[7] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, m_ArrowLength);
566                     m_pnts[8] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
567                     m_pnts[9] = new PointF(dx, dy - m_ArrowLength);
568                     m_pnts[10] = new PointF(dx / 2f, dy);
569                     break;
570                 case ArrowStyleType.UpBow:
571                     m_pCount = 9;
572                     m_pnts = new PointF[m_pCount];
573                     m_pnts[0] = new PointF(0, 0);
574                     m_pnts[1] = new PointF(0, dy);
575                     m_pnts[2] = new PointF(dx, dy);
576                     m_pnts[3] = new PointF(dx, 0);
577                     m_pnts[4] = new PointF(dx - m_BowWidth, 0);
578                     m_pnts[5] = new PointF(dx - m_BowWidth, dy - m_BowHeight);
579                     m_pnts[6] = new PointF(m_BowWidth, dy - m_BowHeight);
580                     m_pnts[7] = new PointF(m_BowWidth, 0);
581                     m_pnts[8] = new PointF(0, 0);
582                     break;
583                 case ArrowStyleType.DownBow:
584                     m_pCount = 9;
585                     m_pnts = new PointF[m_pCount];
586                     m_pnts[0] = new PointF(0, dy);
587                     m_pnts[1] = new PointF(0, 0);
588                     m_pnts[2] = new PointF(dx, 0);
589                     m_pnts[3] = new PointF(dx, dy);
590                     m_pnts[4] = new PointF(dx - m_BowWidth, dy);
591                     m_pnts[5] = new PointF(dx - m_BowWidth, m_BowHeight);
592                     m_pnts[6] = new PointF(m_BowWidth, m_BowHeight);
593                     m_pnts[7] = new PointF(m_BowWidth, dy);
594                     m_pnts[8] = new PointF(0, dy);
595                     break;
596                 case ArrowStyleType.LeftBow:
597                     m_pCount = 9;
598                     m_pnts = new PointF[m_pCount];
599                     m_pnts[0] = new PointF(0, 0);
600                     m_pnts[1] = new PointF(dx, 0);
601                     m_pnts[2] = new PointF(dx, dy);
602                     m_pnts[3] = new PointF(0, dy);
603                     m_pnts[4] = new PointF(0, dy - m_BowHeight);
604                     m_pnts[5] = new PointF(dx - m_BowWidth, dy - m_BowHeight);
605                     m_pnts[6] = new PointF(dx - m_BowWidth, m_BowHeight);
606                     m_pnts[7] = new PointF(0, m_BowHeight);
607                     m_pnts[8] = new PointF(0, 0);
608                     break;
609                 case ArrowStyleType.RightBow:
610                     m_pCount = 9;
611                     m_pnts = new PointF[m_pCount];
612                     m_pnts[0] = new PointF(0, 0);
613                     m_pnts[1] = new PointF(dx, 0);
614                     m_pnts[2] = new PointF(dx, m_BowHeight);
615                     m_pnts[3] = new PointF(m_BowWidth, m_BowHeight);
616                     m_pnts[4] = new PointF(m_BowWidth, dy - m_BowHeight);
617                     m_pnts[5] = new PointF(dx, dy - m_BowHeight);
618                     m_pnts[6] = new PointF(dx, dy);
619                     m_pnts[7] = new PointF(0, dy);
620                     m_pnts[8] = new PointF(0, 0);
621                     break;
622 
623                 default:
624                     break;
625             }
626         }
627 
628         /// <summary>
629         /// 根据箭头坐标设置绘制路径
630         /// </summary>
631         /// <param name="pnts"></param>
632         /// <param name="gp"></param>
633         private void GraphicsPathFromPoints(PointF[] pnts, GraphicsPath gp)
634         {
635             for (int i = 0; i < pnts.Length - 1; i++)
636             {
637                 gp.AddLine(pnts[i].X, pnts[i].Y, pnts[i + 1].X, pnts[i + 1].Y);
638             }
639         }
640         #endregion
641 
642         #region 自定义控件默认值
643 
644         /// <summary>
645         /// 自定义控件默认值
646         /// </summary>
647         private void InitializeComponent()
648         {
649             // 
650             // ArrowLine
651             // 
652             this.Name = "ArrowLine";
653             this.Size = new System.Drawing.Size(48, 48);
654         }
655 
656         #endregion
657     }

 调用方式

 在pictureBox1上添加控件,那么pictureBox1.AllowDrop = true;允许拖拽

 1 ArrowControll objArrowControll = new ArrowControll();
 2             //objArrowControll.AntiAlias = false;
 3             objArrowControll.ArrowBodyWidth = 8F;
 4             objArrowControll.ArrowLength = 20F;
 5             objArrowControll.ArrowStyle = ArrowStyleType.Left;
 6             //objArrowControll.BowHeight = 4F;
 7             //objArrowControll.BowWidth = 4F;
 8             objArrowControll.ColorLinearDirection = LinearGradientDirection.Horizontal;
 9             //objArrowControll.FrameEnabled = false;
10             //objArrowControll.LinearGradientRect = new System.Drawing.Rectangle(0, 0, 48, 48);
11             //objArrowControll.LinearGradientUsingClient = true;
12             objArrowControll.Location = new System.Drawing.Point(200, 100);
13             //objArrowControll.Name = "arrowLine1";
14             objArrowControll.NormalEndColor = System.Drawing.Color.DarkOrange;
15             objArrowControll.NormalStartColor = System.Drawing.Color.Blue;
16             //objArrowControll.Size = new System.Drawing.Size(90, 22);
17             //objArrowControll.TabIndex = 3;
18             //objArrowControll.Text = "arrowLine1";
19 
20             //控件鼠标按下事件
21             objArrowControll.MouseDown += ObjArrowControll_MouseDown;
22             //控件鼠标移动事件
23             objArrowControll.MouseMove += ObjArrowControll_MouseMove;
24             //控件鼠标弹起事件
25             objArrowControll.MouseUp += ObjArrowControll_MouseUp;
26 
27             pictureBox1.Controls.Add(objArrowControll);

控件事件 

1         Point mouseDownPoint = new Point(); //记录拖拽过程鼠标位置
2         bool isMove = false;    //判断鼠标在picturebox上移动时,是否处于拖拽过程(鼠标左键是否按下)
 1 private void ObjArrowControll_MouseDown(object sender, MouseEventArgs e)
 2         {
 3             ArrowControll controll = (ArrowControll)sender;
 4             //左键的话,标志位为true(表示拖拽开始)
 5             if ((e.Button == System.Windows.Forms.MouseButtons.Left))
 6             {
 7                 mouseDownPoint.X = Cursor.Position.X;
 8                 mouseDownPoint.Y = Cursor.Position.Y;
 9                 isMove = true;
10                 controll.Focus();
11             }
12         }
13         private void ObjArrowControll_MouseMove(object sender, MouseEventArgs e)
14         {
15             ArrowControll controll = (ArrowControll)sender;
16             if (isMove)
17             {
18                 int x, y;
19                 int moveX, moveY;
20                 moveX = Cursor.Position.X - mouseDownPoint.X;
21                 moveY = Cursor.Position.Y - mouseDownPoint.Y;
22                 x = controll.Location.X + moveX;
23                 y = controll.Location.Y + moveY;
24                 controll.Location = new Point(x, y);
25                 mouseDownPoint.X = Cursor.Position.X;
26                 mouseDownPoint.Y = Cursor.Position.Y;
27             }
28         }
29         private void ObjArrowControll_MouseUp(object sender, MouseEventArgs e)
30         {
31             if (e.Button == MouseButtons.Left)
32             {
33                 isMove = false;
34             }
35         }
原文地址:https://www.cnblogs.com/WarBlog/p/11194725.html