分享

C# 实现拖拉控件改变位置与大小

 goodwangLib 2018-01-31

前言:

  很多时候我们需要在运行时,动态地改变控件的位置以及大小,以获得更好的布局。比如说实际项目中的可自定义的报表、可自定义的单据等诸如此类。它们有个特点就是允许客户或者二次开发人员设计它们需要的界面设置功能。

  本人以前也做过可自定义系统,包括界面和功能,主要为了减少开发人员的工作量以及程序的灵活性和健壮性。

  本篇主要讨论下,在运行时如何实现拖拉控件,达到改变控件位置与大小。功能将模拟VS设计界面时的拖拉功能。

  (本篇暂不涉及多控件同时操作)

一、技术概述

  其实实现运行时控件的拖拉并不难,主要是改变控件的Location与Size即可。动态调整时再捕获MouseDown、MouseMove及MouseUp事件来实时修改上述两个属性就可以实现。

 

二、功能规划

  在此之前,我们先来看下.net设计界面,一旦选中某个控件时,将会出现如下图的边框:

  

  之后就可以通过拖拉出现的边框改变其大小。而改变控件的位置,实际上是当鼠标点击在控件内部拖动时实现的。

  所有本例也将功能分为两个部分实现,分别为控件内部拖动改变位置与控件边框拖拉改变大小。

 

三、具体实现

1.拖动控件改变位置

  首先,新建一个项目,然后添加一个类,取名叫MoveControl,该类用来给控件挂载事件实现拖动。

  接着在该类中添加字段currentControl,用来保存需要操作的控件,即通过构造函数传递的控件。

  接着创建一方法--AddEvents,用来给当前的控件挂载事件。

  代码如下:   

DragControl
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Windows.Forms; 5 using System.Drawing; 6 7 namespace DragControl 8 { 9 public class MoveControl10 {11 #region Constructors12 public MoveControl(Control ctrl)13 {14 currentControl = ctrl;15 AddEvents();16 }17 #endregion18 19 #region Fields20 private Control currentControl; //传入的控件21 #endregion22 23 #region Properties24 25 #endregion26 27 #region Methods28 /// 29 /// 挂载事件30 /// 31 private void AddEvents()32 {33 currentControl.MouseClick += new MouseEventHandler(MouseClick);34 currentControl.MouseDown += new MouseEventHandler(MouseDown);35 currentControl.MouseMove += new MouseEventHandler(MouseMove);36 currentControl.MouseUp += new MouseEventHandler(MouseUp);37 }38 #endregion39 40 #region Events41 /// 42 /// 鼠标单击事件:用来显示边框43 /// 44 /// 45 /// 46 void MouseClick(object sender, MouseEventArgs e)47 {48 }49 50 /// 51 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标52 /// 53 void MouseDown(object sender, MouseEventArgs e)54 {55 56 }57 58 /// 59 /// 鼠标移动事件:让控件跟着鼠标移动60 /// 61 void MouseMove(object sender, MouseEventArgs e)62 {63 }64 65 /// 66 /// 鼠标弹起事件:让自定义的边框出现67 /// 68 void MouseUp(object sender, MouseEventArgs e)69 {70 }71 #endregion72 }73 }

  接着我们需要实现MouseDown、MouseMove、MouseUp三个事件。

  不过在此之前,我们必须要弄清楚,移动即表示坐标的改变,所以必定要有个起始坐标和终点坐标。

  所以我们在MoveControl类中加入两个字段。

private Point pPoint; //上个鼠标坐标private Point cPoint; //当前鼠标坐标

  而且在开始拖动之前,我们肯定需要先单击一次控件。在MouseDown时获取当前光标的位置,保存到pPoint中。

  (此处用Cursor获得坐标的好处,就是忽略掉容器的麻烦问题)

1 /// 2 /// 鼠标单击事件:用来显示边框3 /// 4 void MouseClick(object sender, MouseEventArgs e)5 {6 pPoint = Cursor.Position; 7 }

  接着便实现MouseMove的事件,当鼠标左键按下时,接着移动鼠标后,继续鼠标移动后的坐标,然后与MouseDown时记下的坐标相减,就得到鼠标的位移值,接着控件的Location加上该位移值即可,然后更新pPoint。  

1 /// 2 /// 鼠标移动事件:让控件跟着鼠标移动 3 /// 4 void MouseMove(object sender, MouseEventArgs e) 5 { 6 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll 7 //当鼠标左键按下时才触发 8 if (e.Button == MouseButtons.Left) 9 {10 cPoint = Cursor.Position; //获得当前鼠标位置11 int x = cPoint.X - pPoint.X;12 int y = cPoint.Y - pPoint.Y;13 currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y);14 pPoint = cPoint;15 }16 }

  由于此时还没涉及到边框,所以MouseUp暂时不用处理。至此拖动的基本功能已经实现!

  目前MoveControl的完整代码如下:  

MoveControl
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Windows.Forms; 5 using System.Drawing; 6 7 namespace DragControl 8 { 9 public class MoveControl10 {11 #region Constructors12 public MoveControl(Control ctrl)13 {14 currentControl = ctrl;15 AddEvents();16 }17 #endregion18 19 #region Fields20 private Control currentControl; //传入的控件21 private Point pPoint; //上个鼠标坐标22 private Point cPoint; //当前鼠标坐标23 #endregion24 25 #region Properties26 27 #endregion28 29 #region Methods30 /// 31 /// 挂载事件32 /// 33 private void AddEvents()34 {35 currentControl.MouseDown += new MouseEventHandler(MouseDown);36 currentControl.MouseMove += new MouseEventHandler(MouseMove);37 currentControl.MouseUp += new MouseEventHandler(MouseUp);38 }39 40 /// 41 /// 绘制拖拉时的黑色边框42 /// 43 public static void DrawDragBound(Control ctrl)44 {45 ctrl.Refresh();46 Graphics g = ctrl.CreateGraphics();47 int width = ctrl.Width;48 int height = ctrl.Height;49 Point[] ps = new Point[5]{new Point(0,0),new Point(width -1,0),50 new Point(width -1,height -1),new Point(0,height-1),new Point(0,0)};51 g.DrawLines(new Pen(Color.Black), ps);52 } 53 #endregion54 55 #region Events56 /// 57 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标58 /// 59 void MouseDown(object sender, MouseEventArgs e)60 {61 pPoint = Cursor.Position;62 }63 64 /// 65 /// 鼠标移动事件:让控件跟着鼠标移动66 /// 67 void MouseMove(object sender, MouseEventArgs e)68 {69 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll70 //当鼠标左键按下时才触发71 if (e.Button == MouseButtons.Left)72 {73 MoveControl.DrawDragBound(this.currentControl);74 cPoint = Cursor.Position; //获得当前鼠标位置75 int x = cPoint.X - pPoint.X;76 int y = cPoint.Y - pPoint.Y;77 currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y);78 pPoint = cPoint;79 }80 }81 82 /// 83 /// 鼠标弹起事件:让自定义的边框出现84 /// 85 void MouseUp(object sender, MouseEventArgs e)86 {87 this.currentControl.Refresh();88 }89 #endregion90 }91 }

 

 

  下面我们来测试下拖动的功能。

  创建一个Form窗体,可以再界面上添加你要测试的控件类型,此处我只用TextBox左下测试。在Load的中添加以下代码,将Form中的所有控件挂载上拖拉功能。

1 private void Form1_Load(object sender, EventArgs e)2 {3 foreach (Control ctrl in this.Controls)4 {5 new MoveControl(ctrl);6 }7 }

  

  此时,有心人可能会发现VS中拖动控件时,将会出现黑色边框,而处于没有。

  这也很简单,我们在MouseMove时加上如下代码即可。

1 /// 2 /// 绘制拖拉时的黑色边框 3 /// 4 public static void DrawDragBound(Control ctrl) 5 { 6 ctrl.Refresh(); 7 Graphics g = ctrl.CreateGraphics(); 8 int width = ctrl.Width; 9 int height = ctrl.Height;10 Point[] ps = new Point[5]{new Point(0,0),new Point(width -1,0),11 new Point(width -1,height -1),new Point(0,height-1),new Point(0,0)};12 g.DrawLines(new Pen(Color.Black), ps);13 } 14 15 16 /// 17 /// 鼠标移动事件:让控件跟着鼠标移动18 /// 19 void MouseMove(object sender, MouseEventArgs e)20 {21 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll22 //当鼠标左键按下时才触发23 if (e.Button == MouseButtons.Left)24 {25 MoveControl.DrawDragBound(this.currentControl);26 cPoint = Cursor.Position; //获得当前鼠标位置27 int x = cPoint.X - pPoint.X;28 int y = cPoint.Y - pPoint.Y;29 currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y);30 pPoint = cPoint;31 }32 }

  同时要在MoveUp的时候,刷新一下自己,让黑色边框消失掉!  

1 /// 2 /// 鼠标弹起事件:让自定义的边框出现3 /// 4 void MouseUp(object sender, MouseEventArgs e)5 {6 this.currentControl.Refresh();7 }

 

  接着用没有边框的控件测试下就会很明显。如下图所示:   

 

 

 

2.通过边框拖拉控件改变大小

  此处的主要思路为:点击控件的时候,创建一个自定义的用户控件,该用户控件响应区域就是传入控件的边框区域,同时给它画上虚线与8个小圆圈。

  第一、创建用户控件--FrameControl(边框控件),然后增加一个字段用来保存传入的控件,还有加载事件,此处类同前面的MoveControl。

FrameControl
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 namespace DragControl11 {12 public partial class FrameControl : UserControl13 {14 #region Constructors15 public FrameControl(Control ctrl)16 {17 baseControl = ctrl;18 AddEvents();19 }20 #endregion21 22 #region Fields23 Control baseControl; //基础控件,即被包围的控件24 #endregion25 26 #region Methods27 /// 28 /// 加载事件29 /// 30 private void AddEvents()31 {32 this.Name = 'FrameControl' + baseControl.Name;33 this.MouseDown += new MouseEventHandler(FrameControl_MouseDown);34 this.MouseMove += new MouseEventHandler(FrameControl_MouseMove);35 this.MouseUp += new MouseEventHandler(FrameControl_MouseUp);36 }37 38 #endregion39 40 #region Events41 /// 42 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标43 /// 44 void FrameControl_MouseDown(object sender, MouseEventArgs e)45 {46 47 }48 49 /// 50 /// 鼠标移动事件:让控件跟着鼠标移动51 /// 52 void FrameControl_MouseMove(object sender, MouseEventArgs e)53 {54 55 }56 57 /// 58 /// 鼠标弹起事件:让自定义的边框出现59 /// 60 void FrameControl_MouseUp(object sender, MouseEventArgs e)61 {62 63 }64 #endregion65 }66 }

  做完这些准备工作后,将到了主要的部分,就是给控件画边框。

  整个边框分为三个部分:四边框(用来设置可视区域与区域)+四条虚线(只用来显示)+八个小圆圈(用来斜角拖拉)。

  所以要建立三个字段,用来分别保存这个数据。

Rectangle[] smallRects = new Rectangle[8];//边框中的八个小圆圈 Rectangle[] sideRects = new Rectangle[4];//四条边框,用来做响应区域 Point[] linePoints = new Point[5];//四条边,用于画虚线

  接着就是创建用户控件的可视区域,和上面的三个变量数值。

  (以下计算位置的代码,有兴趣的人可以研究下,没有的就直接Copy)  

创建边框
1 #region 创建边框 2 /// 3 /// 建立控件可视区域 4 /// 5 private void CreateBounds() 6 { 7 //创建边界 8 int X = baseControl.Bounds.X - square.Width - 1; 9 int Y = baseControl.Bounds.Y - square.Height - 1;10 int Height = baseControl.Bounds.Height + (square.Height * 2) + 2;11 int Width = baseControl.Bounds.Width + (square.Width * 2) + 2;12 this.Bounds = new Rectangle(X, Y, Width, Height);13 this.BringToFront();14 SetRectangles();15 //设置可视区域16 this.Region = new Region(BuildFrame());17 g = this.CreateGraphics();18 }19 20 /// 21 /// 设置定义8个小矩形的范围22 /// 23 void SetRectangles()24 {25 //左上26 smallRects[0] = new Rectangle(new Point(0, 0), square);27 //右上28 smallRects[1] = new Rectangle(new Point(this.Width - square.Width - 1, 0), square);29 //左下30 smallRects[2] = new Rectangle(new Point(0, this.Height - square.Height - 1), square);31 //右下32 smallRects[3] = new Rectangle(new Point(this.Width - square.Width - 1, this.Height - square.Height - 1), square);33 //上中34 smallRects[4] = new Rectangle(new Point(this.Width / 2 - 1, 0), square);35 //下中36 smallRects[5] = new Rectangle(new Point(this.Width / 2 - 1, this.Height - square.Height - 1), square);37 //左中38 smallRects[6] = new Rectangle(new Point(0, this.Height / 2 - 1), square);39 //右中40 smallRects[7] = new Rectangle(new Point(square.Width + baseControl.Width + 1, this.Height / 2 - 1), square);41 42 //四条边线43 //左上44 linePoints[0] = new Point(square.Width / 2, square.Height / 2);45 //右上46 linePoints[1] = new Point(this.Width - square.Width / 2 - 1, square.Height / 2);47 //右下48 linePoints[2] = new Point(this.Width - square.Width / 2 - 1, this.Height - square.Height / 2);49 //左下50 linePoints[3] = new Point(square.Width / 2, this.Height - square.Height / 2 - 1);51 //左上52 linePoints[4] = new Point(square.Width / 2, square.Height / 2);53 54 //整个包括周围边框的范围55 ControlRect = new Rectangle(new Point(0, 0), this.Bounds.Size);56 }57 58 /// 59 /// 设置边框控件可视区域60 /// 61 /// 62 private GraphicsPath BuildFrame()63 {64 GraphicsPath path = new GraphicsPath();65 //上边框66 sideRects[0] = new Rectangle(0, 0, this.Width - square.Width - 1, square.Height + 1);67 //左边框68 sideRects[1] = new Rectangle(0, square.Height + 1, square.Width + 1, this.Height - square.Height - 1);69 //下边框70 sideRects[2] = new Rectangle(square.Width + 1, this.Height - square.Height - 1, this.Width - square.Width - 1, square.Height + 1);71 //右边框72 sideRects[3] = new Rectangle(this.Width - square.Width - 1, 0, square.Width + 1, this.Height - square.Height - 1);73 74 path.AddRectangle(sideRects[0]);75 path.AddRectangle(sideRects[1]);76 path.AddRectangle(sideRects[2]);77 path.AddRectangle(sideRects[3]);78 return path;79 }80 #endregion

   设置完位置后,接着就是绘制的工作。增加一个Draw的方法用来画,同时设置为Public。此处不用控件的Paint,而是让用户调用,只因为这样方便在不同控件之间切换,也就是一个容器中,只有当前控件有边框。

1 /// 2 /// 绘图 3 /// 4 public void Draw() 5 { 6 this.BringToFront(); 7 Pen pen = new Pen(Color.Black); 8 pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果 9 g.DrawLines(pen, linePoints);//绘制四条边线10 g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部11 foreach (Rectangle smallRect in smallRects)12 {13 g.DrawEllipse(Pens.Black, smallRect); //绘制8个小椭圆14 }15 //g.DrawRectangles(Pens.Black, smallRects); //绘制8个小矩形的黑色边线16 }

  做到这里,我们可以去前台看一下效果,不过再此之前,我们需要调用该用户控件。

  调用的地方就是在控件上点击的时候,所以在MoveControl中加入MouseClick的事件。

1 /// 2 /// 鼠标单击事件:用来显示边框 3 /// 4 /// 5 /// 6 protected void MouseClick(object sender, MouseEventArgs e) 7 { 8 this.currentControl.Parent.Refresh();//刷新父容器,清除掉其他控件的边框 9 this.currentControl.BringToFront();10 fc = new FrameControl(this.currentControl);11 this.currentControl.Parent.Controls.Add(fc);12 fc.Visible = true;13 fc.Draw();14 }

  这时有了边框之后会有一个小问题,就是拖动控件的时候,控件移动了,但是边框还留在原地。

  所以,这里需要注意的,就是移动的时候,将边框控件隐藏掉,当MouseUp的时候再显示。

 

  此时的完整代码如下:

MoveControl
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Windows.Forms; 5 using System.Drawing; 6 7 namespace DragControl 8 { 9 public class MoveControl 10 { 11 #region Constructors 12 public MoveControl(Control ctrl) 13 { 14 currentControl = ctrl; 15 AddEvents(); 16 } 17 #endregion 18 19 #region Fields 20 private Control currentControl; //传入的控件 21 private Point pPoint; //上个鼠标坐标 22 private Point cPoint; //当前鼠标坐标 23 FrameControl fc;//边框控件 24 #endregion 25 26 #region Properties 27 28 #endregion 29 30 #region Methods 31 /// 32 /// 挂载事件 33 /// 34 private void AddEvents() 35 { 36 currentControl.MouseClick += new MouseEventHandler(MouseClick); 37 currentControl.MouseDown += new MouseEventHandler(MouseDown); 38 currentControl.MouseMove += new MouseEventHandler(MouseMove); 39 currentControl.MouseUp += new MouseEventHandler(MouseUp); 40 } 41 42 /// 43 /// 绘制拖拉时的黑色边框 44 /// 45 public static void DrawDragBound(Control ctrl) 46 { 47 ctrl.Refresh(); 48 Graphics g = ctrl.CreateGraphics(); 49 int width = ctrl.Width; 50 int height = ctrl.Height; 51 Point[] ps = new Point[5]{new Point(0,0),new Point(width -1,0), 52 new Point(width -1,height -1),new Point(0,height-1),new Point(0,0)}; 53 g.DrawLines(new Pen(Color.Black), ps); 54 } 55 #endregion 56 57 #region Events 58 /// 59 /// 鼠标单击事件:用来显示边框 60 /// 61 /// 62 /// 63 protected void MouseClick(object sender, MouseEventArgs e) 64 { 65 this.currentControl.Parent.Refresh();//刷新父容器,清除掉其他控件的边框 66 this.currentControl.BringToFront(); 67 fc = new FrameControl(this.currentControl); 68 this.currentControl.Parent.Controls.Add(fc); 69 fc.Visible = true; 70 fc.Draw(); 71 } 72 73 /// 74 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标 75 /// 76 void MouseDown(object sender, MouseEventArgs e) 77 { 78 pPoint = Cursor.Position; 79 } 80 81 /// 82 /// 鼠标移动事件:让控件跟着鼠标移动 83 /// 84 void MouseMove(object sender, MouseEventArgs e) 85 { 86 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll 87 //当鼠标左键按下时才触发 88 if (e.Button == MouseButtons.Left) 89 { 90 MoveControl.DrawDragBound(this.currentControl); 91 if (fc != null) fc.Visible = false; //先隐藏 92 cPoint = Cursor.Position; //获得当前鼠标位置 93 int x = cPoint.X - pPoint.X; 94 int y = cPoint.Y - pPoint.Y; 95 currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y); 96 pPoint = cPoint; 97 } 98 } 99 100 /// 101 /// 鼠标弹起事件:让自定义的边框出现102 /// 103 void MouseUp(object sender, MouseEventArgs e)104 {105 this.currentControl.Refresh();106 if (fc != null)107 {108 fc.Visible = true;109 fc.Draw();110 }111 }112 #endregion113 }114 }
FrameControl
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using System.Text; 7 using System.Windows.Forms; 8 using System.Drawing.Drawing2D; 9 10 namespace DragControl 11 { 12 public partial class FrameControl : UserControl 13 { 14 #region Constructors 15 public FrameControl(Control ctrl) 16 { 17 baseControl = ctrl; 18 AddEvents(); 19 CreateBounds(); 20 } 21 #endregion 22 23 #region Fields 24 const int Band = 6; //调整大小的响应边框 25 Size square = new Size(Band, Band);//小矩形大小 26 Control baseControl; //基础控件,即被包围的控件 27 Rectangle[] smallRects = new Rectangle[8];//边框中的八个小圆圈 28 Rectangle[] sideRects = new Rectangle[4];//四条边框,用来做响应区域 29 Point[] linePoints = new Point[5];//四条边,用于画虚线 30 Graphics g; //画图板 31 Rectangle ControlRect; //控件包含边框的区域 32 #endregion 33 34 #region Methods 35 /// 36 /// 加载事件 37 /// 38 private void AddEvents() 39 { 40 this.Name = 'FrameControl' + baseControl.Name; 41 this.MouseDown += new MouseEventHandler(FrameControl_MouseDown); 42 this.MouseMove += new MouseEventHandler(FrameControl_MouseMove); 43 this.MouseUp += new MouseEventHandler(FrameControl_MouseUp); 44 } 45 46 #region 创建边框 47 /// 48 /// 建立控件可视区域 49 /// 50 private void CreateBounds() 51 { 52 //创建边界 53 int X = baseControl.Bounds.X - square.Width - 1; 54 int Y = baseControl.Bounds.Y - square.Height - 1; 55 int Height = baseControl.Bounds.Height + (square.Height * 2) + 2; 56 int Width = baseControl.Bounds.Width + (square.Width * 2) + 2; 57 this.Bounds = new Rectangle(X, Y, Width, Height); 58 this.BringToFront(); 59 SetRectangles(); 60 //设置可视区域 61 this.Region = new Region(BuildFrame()); 62 g = this.CreateGraphics(); 63 } 64 65 /// 66 /// 设置定义8个小矩形的范围 67 /// 68 void SetRectangles() 69 { 70 //左上 71 smallRects[0] = new Rectangle(new Point(0, 0), square); 72 //右上 73 smallRects[1] = new Rectangle(new Point(this.Width - square.Width - 1, 0), square); 74 //左下 75 smallRects[2] = new Rectangle(new Point(0, this.Height - square.Height - 1), square); 76 //右下 77 smallRects[3] = new Rectangle(new Point(this.Width - square.Width - 1, this.Height - square.Height - 1), square); 78 //上中 79 smallRects[4] = new Rectangle(new Point(this.Width / 2 - 1, 0), square); 80 //下中 81 smallRects[5] = new Rectangle(new Point(this.Width / 2 - 1, this.Height - square.Height - 1), square); 82 //左中 83 smallRects[6] = new Rectangle(new Point(0, this.Height / 2 - 1), square); 84 //右中 85 smallRects[7] = new Rectangle(new Point(square.Width + baseControl.Width + 1, this.Height / 2 - 1), square); 86 87 //四条边线 88 //左上 89 linePoints[0] = new Point(square.Width / 2, square.Height / 2); 90 //右上 91 linePoints[1] = new Point(this.Width - square.Width / 2 - 1, square.Height / 2); 92 //右下 93 linePoints[2] = new Point(this.Width - square.Width / 2 - 1, this.Height - square.Height / 2); 94 //左下 95 linePoints[3] = new Point(square.Width / 2, this.Height - square.Height / 2 - 1); 96 //左上 97 linePoints[4] = new Point(square.Width / 2, square.Height / 2); 98 99 //整个包括周围边框的范围100 ControlRect = new Rectangle(new Point(0, 0), this.Bounds.Size);101 }102 103 /// 104 /// 设置边框控件可视区域105 /// 106 /// 107 private GraphicsPath BuildFrame()108 {109 GraphicsPath path = new GraphicsPath();110 //上边框111 sideRects[0] = new Rectangle(0, 0, this.Width - square.Width - 1, square.Height + 1);112 //左边框113 sideRects[1] = new Rectangle(0, square.Height + 1, square.Width + 1, this.Height - square.Height - 1);114 //下边框115 sideRects[2] = new Rectangle(square.Width + 1, this.Height - square.Height - 1, this.Width - square.Width - 1, square.Height + 1);116 //右边框117 sideRects[3] = new Rectangle(this.Width - square.Width - 1, 0, square.Width + 1, this.Height - square.Height - 1);118 119 path.AddRectangle(sideRects[0]);120 path.AddRectangle(sideRects[1]);121 path.AddRectangle(sideRects[2]);122 path.AddRectangle(sideRects[3]);123 return path;124 }125 #endregion126 127 /// 128 /// 绘图129 /// 130 public void Draw()131 {132 this.BringToFront();133 Pen pen = new Pen(Color.Black);134 pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果135 g.DrawLines(pen, linePoints);//绘制四条边线136 g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部137 foreach (Rectangle smallRect in smallRects)138 {139 g.DrawEllipse(Pens.Black, smallRect); //绘制8个小椭圆140 }141 //g.DrawRectangles(Pens.Black, smallRects); //绘制8个小矩形的黑色边线142 }143 144 #endregion145 146 #region Events147 /// 148 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标149 /// 150 void FrameControl_MouseDown(object sender, MouseEventArgs e)151 {152 153 }154 155 /// 156 /// 鼠标移动事件:让控件跟着鼠标移动157 /// 158 void FrameControl_MouseMove(object sender, MouseEventArgs e)159 {160 161 }162 163 /// 164 /// 鼠标弹起事件:让自定义的边框出现165 /// 166 void FrameControl_MouseUp(object sender, MouseEventArgs e)167 {168 169 }170 #endregion171 }172 }

  测试界面:

 

  到目前为止,还只是有边框,下面将实现拖拉功能。

  首先来实现,当鼠标放在响应区域的时候,根据不同的位置显示不同的箭头样子。

  为此先创建一个枚举,用来记录当前鼠标的位置,等拖拉的时候根据该枚举值做不同的计算。

1 /// 2 /// 鼠标在控件中位置 3 /// 4 enum MousePosOnCtrl 5 { 6 NONE = 0, 7 TOP = 1, 8 RIGHT = 2, 9 BOTTOM = 3,10 LEFT = 4,11 TOPLEFT = 5,12 TOPRIGHT = 6,13 BOTTOMLEFT = 7,14 BOTTOMRIGHT = 8,15 }

  创建一个方法,用来改变光标的样子以及枚举值

1 /// 2 /// 设置光标状态 3 /// 4 public bool SetCursorShape(int x, int y) 5 { 6 Point point = new Point(x, y); 7 if (!ControlRect.Contains(point)) 8 { 9 Cursor.Current = Cursors.Arrow;10 return false;11 }12 else if (smallRects[0].Contains(point))13 {14 Cursor.Current = Cursors.SizeNWSE;15 mpoc = MousePosOnCtrl.TOPLEFT;16 }17 else if (smallRects[1].Contains(point))18 {19 Cursor.Current = Cursors.SizeNESW;20 mpoc = MousePosOnCtrl.TOPRIGHT;21 }22 else if (smallRects[2].Contains(point))23 {24 Cursor.Current = Cursors.SizeNESW;25 mpoc = MousePosOnCtrl.BOTTOMLEFT;26 }27 else if (smallRects[3].Contains(point))28 {29 Cursor.Current = Cursors.SizeNWSE;30 mpoc = MousePosOnCtrl.BOTTOMRIGHT;31 }32 else if (sideRects[0].Contains(point))33 {34 Cursor.Current = Cursors.SizeNS;35 mpoc = MousePosOnCtrl.TOP;36 }37 else if (sideRects[1].Contains(point))38 {39 Cursor.Current = Cursors.SizeWE;40 mpoc = MousePosOnCtrl.LEFT;41 }42 else if (sideRects[2].Contains(point))43 {44 Cursor.Current = Cursors.SizeNS;45 mpoc = MousePosOnCtrl.BOTTOM;46 }47 else if (sideRects[3].Contains(point))48 {49 Cursor.Current = Cursors.SizeWE;50 mpoc = MousePosOnCtrl.RIGHT;51 }52 else53 {54 Cursor.Current = Cursors.Arrow;55 }56 return true;57 }

  接着就是处理相关的三大事件MouseDown、MouseMove、MouseUp来实现拖拉。如同MoveControl都要增加以下两个字段。

private Point pPoint; //上个鼠标坐标 private Point cPoint; //当前鼠标坐标
1 /// 2 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标 3 /// 4 void FrameControl_MouseDown(object sender, MouseEventArgs e) 5 { 6 pPoint = Cursor.Position; 7 } 8 9 /// 10 /// 鼠标移动事件:让控件跟着鼠标移动11 /// 12 void FrameControl_MouseMove(object sender, MouseEventArgs e)13 {14 if (e.Button == MouseButtons.Left)15 {16 this.Visible = false;17 MoveControl.DrawDragBound(baseControl);18 ControlMove();19 }20 else21 {22 this.Visible = true;23 SetCursorShape(e.X, e.Y); //更新鼠标指针样式24 }25 }26 27 /// 28 /// 鼠标弹起事件:让自定义的边框出现29 /// 30 void FrameControl_MouseUp(object sender, MouseEventArgs e)31 {32 this.baseControl.Refresh(); //刷掉黑色边框33 this.Visible = true;34 CreateBounds();35 Draw();36 }

  在上面的MouseMove中多了一个方法--ControlMove,这个就是根据不同的枚举值,计算控件的移动方式和大小的方法。该方法中同时对控件的最小宽度和高度做了处理。添加如下两个字段。

private int MinWidth = 20; //最小宽度 private int MinHeight = 20;//最小高度
1 /// 2 /// 控件移动 3 /// 4 private void ControlMove() 5 { 6 cPoint = Cursor.Position; 7 int x = cPoint.X - pPoint.X; 8 int y = cPoint.Y - pPoint.Y; 9 switch (this.mpoc) 10 { 11 case MousePosOnCtrl.TOP: 12 if (baseControl.Height - y > MinHeight) 13 { 14 baseControl.Top += y; 15 baseControl.Height -= y; 16 } 17 else 18 { 19 baseControl.Top -= MinHeight - baseControl.Height; 20 baseControl.Height = MinHeight; 21 } 22 break; 23 case MousePosOnCtrl.BOTTOM: 24 if (baseControl.Height + y > MinHeight) 25 { 26 baseControl.Height += y; 27 } 28 else 29 { 30 baseControl.Height = MinHeight; 31 } 32 break; 33 case MousePosOnCtrl.LEFT: 34 if (baseControl.Width - x > MinWidth) 35 { 36 baseControl.Left += x; 37 baseControl.Width -= x; 38 } 39 else 40 { 41 baseControl.Left -= MinWidth - baseControl.Width; 42 baseControl.Width = MinWidth; 43 } 44 45 break; 46 case MousePosOnCtrl.RIGHT: 47 if (baseControl.Width + x > MinWidth) 48 { 49 baseControl.Width += x; 50 } 51 else 52 { 53 baseControl.Width = MinWidth; 54 } 55 break; 56 case MousePosOnCtrl.TOPLEFT: 57 if (baseControl.Height - y > MinHeight) 58 { 59 baseControl.Top += y; 60 baseControl.Height -= y; 61 } 62 else 63 { 64 baseControl.Top -= MinHeight - baseControl.Height; 65 baseControl.Height = MinHeight; 66 } 67 if (baseControl.Width - x > MinWidth) 68 { 69 baseControl.Left += x; 70 baseControl.Width -= x; 71 } 72 else 73 { 74 baseControl.Left -= MinWidth - baseControl.Width; 75 baseControl.Width = MinWidth; 76 } 77 break; 78 case MousePosOnCtrl.TOPRIGHT: 79 if (baseControl.Height - y > MinHeight) 80 { 81 baseControl.Top += y; 82 baseControl.Height -= y; 83 } 84 else 85 { 86 baseControl.Top -= MinHeight - baseControl.Height; 87 baseControl.Height = MinHeight; 88 } 89 if (baseControl.Width + x > MinWidth) 90 { 91 baseControl.Width += x; 92 } 93 else 94 { 95 baseControl.Width = MinWidth; 96 } 97 break; 98 case MousePosOnCtrl.BOTTOMLEFT: 99 if (baseControl.Height + y > MinHeight)100 {101 baseControl.Height += y;102 }103 else104 {105 baseControl.Height = MinHeight;106 }107 if (baseControl.Width - x > MinWidth)108 {109 baseControl.Left += x;110 baseControl.Width -= x;111 }112 else113 {114 baseControl.Left -= MinWidth - baseControl.Width;115 baseControl.Width = MinWidth;116 }117 break;118 case MousePosOnCtrl.BOTTOMRIGHT:119 if (baseControl.Height + y > MinHeight)120 {121 baseControl.Height += y;122 }123 else124 {125 baseControl.Height = MinHeight;126 }127 if (baseControl.Width + x > MinWidth)128 {129 baseControl.Width += x;130 }131 else132 {133 baseControl.Width = MinWidth;134 }135 break;136 137 }138 pPoint = Cursor.Position;139 }

  到此为止,功能已经基本上实现。

  完成代码如下:

MoveControl
1 /****************************************************************** 2 * 创 建 人: SamWang 3 * 创建时间: 2012-5-10 16:06 4 * 描 述: 5 * 移动控件但不改变大小 6 * 原 理: 7 * 版 本: V1.0 8 * 环 境: VS2010 9 ******************************************************************/ 10 using System; 11 using System.Collections.Generic; 12 using System.Linq; 13 using System.Text; 14 using System.Windows.Forms; 15 using System.Drawing; 16 17 namespace DragControl 18 { 19 public class MoveControl 20 { 21 #region Constructors 22 public MoveControl(Control ctrl) 23 { 24 currentControl = ctrl; 25 AddEvents(); 26 } 27 #endregion 28 29 #region Fields 30 private Control currentControl; //传入的控件 31 private Point pPoint; //上个鼠标坐标 32 private Point cPoint; //当前鼠标坐标 33 FrameControl fc;//边框控件 34 #endregion 35 36 #region Properties 37 38 #endregion 39 40 #region Methods 41 /// 42 /// 挂载事件 43 /// 44 private void AddEvents() 45 { 46 currentControl.MouseClick += new MouseEventHandler(MouseClick); 47 currentControl.MouseDown += new MouseEventHandler(MouseDown); 48 currentControl.MouseMove += new MouseEventHandler(MouseMove); 49 currentControl.MouseUp += new MouseEventHandler(MouseUp); 50 } 51 52 /// 53 /// 绘制拖拉时的黑色边框 54 /// 55 public static void DrawDragBound(Control ctrl) 56 { 57 ctrl.Refresh(); 58 Graphics g = ctrl.CreateGraphics(); 59 int width = ctrl.Width; 60 int height = ctrl.Height; 61 Point[] ps = new Point[5]{new Point(0,0),new Point(width -1,0), 62 new Point(width -1,height -1),new Point(0,height-1),new Point(0,0)}; 63 g.DrawLines(new Pen(Color.Black), ps); 64 } 65 66 #endregion 67 68 #region Events 69 /// 70 /// 鼠标单击事件:用来显示边框 71 /// 72 /// 73 /// 74 protected void MouseClick(object sender, MouseEventArgs e) 75 { 76 this.currentControl.Parent.Refresh();//刷新父容器,清除掉其他控件的边框 77 this.currentControl.BringToFront(); 78 fc = new FrameControl(this.currentControl); 79 this.currentControl.Parent.Controls.Add(fc); 80 fc.Visible = true; 81 fc.Draw(); 82 } 83 84 /// 85 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标 86 /// 87 void MouseDown(object sender, MouseEventArgs e) 88 { 89 pPoint = Cursor.Position; 90 } 91 92 /// 93 /// 鼠标移动事件:让控件跟着鼠标移动 94 /// 95 void MouseMove(object sender, MouseEventArgs e) 96 { 97 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll 98 //当鼠标左键按下时才触发 99 if (e.Button == MouseButtons.Left)100 {101 MoveControl.DrawDragBound(this.currentControl);102 if(fc != null ) fc.Visible = false; //先隐藏103 cPoint = Cursor.Position;//获得当前鼠标位置104 int x = cPoint.X - pPoint.X;105 int y = cPoint.Y - pPoint.Y;106 currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y);107 pPoint = cPoint;108 }109 }110 111 /// 112 /// 鼠标弹起事件:让自定义的边框出现113 /// 114 void MouseUp(object sender, MouseEventArgs e)115 {116 this.currentControl.Refresh();117 if (fc != null)118 {119 fc.Visible = true;120 fc.Draw();121 }122 }123 #endregion124 }125 }
FrameControl
1 /****************************************************************** 2 * 创 建 人: SamWang 3 * 创建时间: 2012-5-10 17:00 4 * 描 述: 5 * 在控件外部加上边框,用于拖拉,以改变内部控件的大小 6 * 原 理: 7 * 版 本: V1.0 8 * 环 境: VS2010 9 ******************************************************************/ 10 using System; 11 using System.Collections.Generic; 12 using System.Text; 13 using System.Windows.Forms; 14 using System.Drawing; 15 using System.Drawing.Drawing2D; 16 17 namespace DragControl 18 { 19 public class FrameControl : UserControl 20 { 21 #region Constructors 22 /// 23 /// 构造函数 24 /// 25 public FrameControl(Control ctrl) 26 { 27 baseControl = ctrl; 28 AddEvents(); 29 CreateBounds(); 30 } 31 #endregion 32 33 #region Fields 34 const int Band = 6; //调整大小的响应边框 35 private int MinWidth = 20; //最小宽度 36 private int MinHeight = 20;//最小高度 37 Size square = new Size(Band, Band);//小矩形大小 38 Control baseControl; //基础控件,即被包围的控件 39 Rectangle[] smallRects = new Rectangle[8];//边框中的八个小圆圈 40 Rectangle[] sideRects = new Rectangle[4];//四条边框,用来做响应区域 41 Point[] linePoints = new Point[5];//四条边,用于画虚线 42 Graphics g; //画图板 43 Rectangle ControlRect; //控件包含边框的区域 44 private Point pPoint; //上个鼠标坐标 45 private Point cPoint; //当前鼠标坐标 46 private MousePosOnCtrl mpoc; 47 #endregion 48 49 #region Properties 50 /// 51 /// 鼠标在控件中位置 52 /// 53 enum MousePosOnCtrl 54 { 55 NONE = 0, 56 TOP = 1, 57 RIGHT = 2, 58 BOTTOM = 3, 59 LEFT = 4, 60 TOPLEFT = 5, 61 TOPRIGHT = 6, 62 BOTTOMLEFT = 7, 63 BOTTOMRIGHT = 8, 64 } 65 #endregion 66 67 #region Methods 68 /// 69 /// 加载事件 70 /// 71 private void AddEvents() 72 { 73 this.Name = 'FrameControl' + baseControl.Name; 74 this.MouseDown += new MouseEventHandler(FrameControl_MouseDown); 75 this.MouseMove += new MouseEventHandler(FrameControl_MouseMove); 76 this.MouseUp += new MouseEventHandler(FrameControl_MouseUp); 77 } 78 79 #region 创建边框 80 /// 81 /// 建立控件可视区域 82 /// 83 private void CreateBounds() 84 { 85 //创建边界 86 int X = baseControl.Bounds.X - square.Width - 1; 87 int Y = baseControl.Bounds.Y - square.Height - 1; 88 int Height = baseControl.Bounds.Height + (square.Height * 2) + 2; 89 int Width = baseControl.Bounds.Width + (square.Width * 2) + 2; 90 this.Bounds = new Rectangle(X, Y, Width, Height); 91 this.BringToFront(); 92 SetRectangles(); 93 //设置可视区域 94 this.Region = new Region(BuildFrame()); 95 g = this.CreateGraphics(); 96 } 97 98 /// 99 /// 设置定义8个小矩形的范围100 /// 101 void SetRectangles()102 {103 //左上104 smallRects[0] = new Rectangle(new Point(0, 0), square);105 //右上106 smallRects[1] = new Rectangle(new Point(this.Width - square.Width - 1, 0), square);107 //左下108 smallRects[2] = new Rectangle(new Point(0, this.Height - square.Height - 1), square);109 //右下110 smallRects[3] = new Rectangle(new Point(this.Width - square.Width - 1, this.Height - square.Height - 1), square);111 //上中112 smallRects[4] = new Rectangle(new Point(this.Width / 2 - 1, 0), square);113 //下中114 smallRects[5] = new Rectangle(new Point(this.Width / 2 - 1, this.Height - square.Height - 1), square);115 //左中116 smallRects[6] = new Rectangle(new Point(0, this.Height / 2 - 1), square);117 //右中118 smallRects[7] = new Rectangle(new Point(square.Width + baseControl.Width + 1, this.Height / 2 - 1), square);119 120 //四条边线121 //左上122 linePoints[0] = new Point(square.Width / 2, square.Height / 2);123 //右上124 linePoints[1] = new Point(this.Width - square.Width / 2 - 1, square.Height / 2);125 //右下126 linePoints[2] = new Point(this.Width - square.Width / 2 - 1, this.Height - square.Height / 2);127 //左下128 linePoints[3] = new Point(square.Width / 2, this.Height - square.Height / 2 - 1);129 //左上130 linePoints[4] = new Point(square.Width / 2, square.Height / 2);131 132 //整个包括周围边框的范围133 ControlRect = new Rectangle(new Point(0, 0), this.Bounds.Size);134 }135 136 /// 137 /// 设置边框控件可视区域138 /// 139 /// 140 private GraphicsPath BuildFrame()141 {142 GraphicsPath path = new GraphicsPath();143 //上边框144 sideRects[0] = new Rectangle(0, 0, this.Width - square.Width - 1, square.Height + 1);145 //左边框146 sideRects[1] = new Rectangle(0, square.Height + 1, square.Width + 1, this.Height - square.Height - 1);147 //下边框148 sideRects[2] = new Rectangle(square.Width + 1, this.Height - square.Height - 1, this.Width - square.Width - 1, square.Height + 1);149 //右边框150 sideRects[3] = new Rectangle(this.Width - square.Width - 1, 0, square.Width + 1, this.Height - square.Height - 1);151 152 path.AddRectangle(sideRects[0]);153 path.AddRectangle(sideRects[1]);154 path.AddRectangle(sideRects[2]);155 path.AddRectangle(sideRects[3]);156 return path;157 }158 #endregion159 160 /// 161 /// 绘图162 /// 163 public void Draw()164 {165 this.BringToFront();166 //g.FillRectangles(Brushes.LightGray, sideRects); //填充四条边框的内部167 Pen pen = new Pen(Color.Black);168 pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果169 g.DrawLines(pen, linePoints);//绘制四条边线170 g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部171 foreach (Rectangle smallRect in smallRects)172 {173 g.DrawEllipse(Pens.Black, smallRect); //绘制8个小椭圆174 }175 //g.DrawRectangles(Pens.Black, smallRects); //绘制8个小矩形的黑色边线176 }177 178 /// 179 /// 设置光标状态180 /// 181 public bool SetCursorShape(int x, int y)182 {183 Point point = new Point(x, y);184 if (!ControlRect.Contains(point))185 {186 Cursor.Current = Cursors.Arrow;187 return false;188 }189 else if (smallRects[0].Contains(point))190 {191 Cursor.Current = Cursors.SizeNWSE;192 mpoc = MousePosOnCtrl.TOPLEFT;193 }194 else if (smallRects[1].Contains(point))195 {196 Cursor.Current = Cursors.SizeNESW;197 mpoc = MousePosOnCtrl.TOPRIGHT;198 }199 else if (smallRects[2].Contains(point))200 {201 Cursor.Current = Cursors.SizeNESW;202 mpoc = MousePosOnCtrl.BOTTOMLEFT;203 }204 else if (smallRects[3].Contains(point))205 {206 Cursor.Current = Cursors.SizeNWSE;207 mpoc = MousePosOnCtrl.BOTTOMRIGHT;208 }209 else if (sideRects[0].Contains(point))210 {211 Cursor.Current = Cursors.SizeNS;212 mpoc = MousePosOnCtrl.TOP;213 }214 else if (sideRects[1].Contains(point))215 {216 Cursor.Current = Cursors.SizeWE;217 mpoc = MousePosOnCtrl.LEFT;218 }219 else if (sideRects[2].Contains(point))220 {221 Cursor.Current = Cursors.SizeNS;222 mpoc = MousePosOnCtrl.BOTTOM;223 }224 else if (sideRects[3].Contains(point))225 {226 Cursor.Current = Cursors.SizeWE;227 mpoc = MousePosOnCtrl.RIGHT;228 }229 else230 {231 Cursor.Current = Cursors.Arrow;232 }233 return true;234 }235 236 /// 237 /// 控件移动238 /// 239 private void ControlMove()240 {241 cPoint = Cursor.Position;242 int x = cPoint.X - pPoint.X;243 int y = cPoint.Y - pPoint.Y;244 switch (this.mpoc)245 {246 case MousePosOnCtrl.TOP:247 if (baseControl.Height - y > MinHeight)248 {249 baseControl.Top += y;250 baseControl.Height -= y; 251 }252 else253 {254 baseControl.Top -= MinHeight - baseControl.Height;255 baseControl.Height = MinHeight;256 }257 break;258 case MousePosOnCtrl.BOTTOM:259 if (baseControl.Height + y > MinHeight)260 {261 baseControl.Height += y;262 }263 else264 {265 baseControl.Height = MinHeight;266 }267 break;268 case MousePosOnCtrl.LEFT:269 if (baseControl.Width - x > MinWidth)270 {271 baseControl.Left += x;272 baseControl.Width -= x; 273 }274 else275 {276 baseControl.Left -= MinWidth - baseControl.Width;277 baseControl.Width = MinWidth;278 }279 280 break;281 case MousePosOnCtrl.RIGHT:282 if (baseControl.Width + x > MinWidth)283 {284 baseControl.Width += x;285 }286 else287 {288 baseControl.Width = MinWidth;289 }290 break;291 case MousePosOnCtrl.TOPLEFT:292 if (baseControl.Height - y > MinHeight)293 {294 baseControl.Top += y;295 baseControl.Height -= y;296 }297 else298 {299 baseControl.Top -= MinHeight - baseControl.Height;300 baseControl.Height = MinHeight;301 }302 if (baseControl.Width - x > MinWidth)303 {304 baseControl.Left += x;305 baseControl.Width -= x;306 }307 else308 {309 baseControl.Left -= MinWidth - baseControl.Width;310 baseControl.Width = MinWidth;311 }312 break;313 case MousePosOnCtrl.TOPRIGHT:314 if (baseControl.Height - y > MinHeight)315 {316 baseControl.Top += y;317 baseControl.Height -= y;318 }319 else320 {321 baseControl.Top -= MinHeight - baseControl.Height;322 baseControl.Height = MinHeight;323 }324 if (baseControl.Width + x > MinWidth)325 {326 baseControl.Width += x;327 }328 else329 {330 baseControl.Width = MinWidth;331 }332 break; 333 case MousePosOnCtrl.BOTTOMLEFT:334 if (baseControl.Height + y > MinHeight)335 {336 baseControl.Height += y;337 }338 else339 {340 baseControl.Height = MinHeight;341 }342 if (baseControl.Width - x > MinWidth)343 {344 baseControl.Left += x;345 baseControl.Width -= x;346 }347 else348 {349 baseControl.Left -= MinWidth - baseControl.Width;350 baseControl.Width = MinWidth;351 }352 break;353 case MousePosOnCtrl.BOTTOMRIGHT:354 if (baseControl.Height + y > MinHeight)355 {356 baseControl.Height += y;357 }358 else359 {360 baseControl.Height = MinHeight;361 }362 if (baseControl.Width + x > MinWidth)363 {364 baseControl.Width += x;365 }366 else367 {368 baseControl.Width = MinWidth;369 }370 break;371 372 }373 pPoint = Cursor.Position;374 } 375 376 #endregion377 378 #region Events379 /// 380 /// 鼠标按下事件:记录当前鼠标相对窗体的坐标381 /// 382 void FrameControl_MouseDown(object sender, MouseEventArgs e)383 {384 pPoint = Cursor.Position;385 }386 387 /// 388 /// 鼠标移动事件:让控件跟着鼠标移动389 /// 390 void FrameControl_MouseMove(object sender, MouseEventArgs e)391 {392 if (e.Button == MouseButtons.Left)393 {394 this.Visible = false;395 MoveControl.DrawDragBound(baseControl);396 ControlMove();397 }398 else399 {400 this.Visible = true;401 SetCursorShape(e.X, e.Y); //更新鼠标指针样式402 }403 }404 405 /// 406 /// 鼠标弹起事件:让自定义的边框出现407 /// 408 void FrameControl_MouseUp(object sender, MouseEventArgs e)409 {410 this.baseControl.Refresh(); //刷掉黑色边框411 this.Visible = true;412 CreateBounds();413 Draw();414 }415 #endregion416 }417 }

 

四、遗留问题

1.ListBox存在拖拉高度时,存在莫名奇妙的BUG。

2.目前该版本只支持单控件的拖拉,多控件同时拖拉等下次有空再弄。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多