1、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
2、 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 /
3、 鼠标单击事件:用来显示边框43 / 44 / 45 / e46 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 / 鼠标弹起事件:让自定义的边
4、框出现67 / 68 void MouseUp(object sender, MouseEventArgs e)69 70 71 #endregion72 73 接着我们需要实现MouseDown、MouseMove、MouseUp三个事件。不过在此之前,我们必须要弄清楚,移动即表示坐标的改变,所以必定要有个起始坐标和终点坐标。所以我们在MoveControl类中加入两个字段。private Point pPoint; /上个鼠标坐标private Point cPoint; /当前鼠标坐标而且在开始拖动之前,我们肯定需要先单击一次控件。在MouseDown时获取当前光标的位置,保存到pPoi
5、nt中。(此处用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,
6、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
7、 + x, currentControl.Location.Y + y);14 pPoint = cPoint;15 由于此时还没涉及到边框,所以MouseUp暂时不用处理。至此拖动的基本功能已经实现!目前MoveControl的完整代码如下:MoveControl 21 private Point pPoint;22 private Point cPoint;23 #endregion25 #region Properties27 #endregion28 29 #region Methods31 / 挂载事件32 / 33 private void AddEvents()34 35 cur
8、rentControl.MouseDown += new MouseEventHandler(MouseDown);36 currentControl.MouseMove += new MouseEventHandler(MouseMove);37 currentControl.MouseUp += new MouseEventHandler(MouseUp);38 40 / 41 / 绘制拖拉时的黑色边框42 / 43 public static void DrawDragBound(Control ctrl)44 45 ctrl.Refresh();46 Graphics g = ctrl
9、.CreateGraphics();47 int width = ctrl.Width;48 int height = ctrl.Height;49 Point ps = new Point5new 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 / 鼠标按下事件:59
10、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;70 /当鼠标左键按下时才触发71 if (e.Button = MouseButtons.Left)72 73 MoveControl.DrawDragBound(this.currentControl);7
11、4 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.c
12、urrentControl.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 此时,有心人可能会发现VS中拖动控件时,将会出现黑色边框,而处于没有。这也
13、很简单,我们在MouseMove时加上如下代码即可。 2 / 绘制拖拉时的黑色边框 4 public static void DrawDragBound(Control ctrl) 6 ctrl.Refresh(); 7 Graphics g = ctrl.CreateGraphics(); 8 int width = ctrl.Width; 9 int height = ctrl.Height;10 Point ps = new Point5new Point(0,0),new Point(width -1,0),11 new Point(width -1,height -1),new Po
14、int(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;22 /当鼠标左键按下时才触发23 if (e.Button = MouseButtons.Left)24 25 MoveControl.DrawDragBound(this.currentControl);26 c
15、Point = 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的时候,刷新一下自己,让黑色边框消失掉!2 / 鼠标弹起事件:4 void MouseUp(object sender, MouseEventArgs e)
16、6 this.currentControl.Refresh();接着用没有边框的控件测试下就会很明显。如下图所示:2.通过边框拖拉控件改变大小此处的主要思路为:点击控件的时候,创建一个自定义的用户控件,该用户控件响应区域就是传入控件的边框区域,同时给它画上虚线与8个小圆圈。第一、创建用户控件-FrameControl(边框控件),然后增加一个字段用来保存传入的控件,还有加载事件,此处类同前面的MoveControl。FrameControl 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6
17、 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 10 namespace DragControl11 12 public partial class FrameControl : UserControl14 #region Constructors15 public FrameControl(Control ctrl)16 17 baseControl = ctrl;18 AddEvents();19 20 #endregion21 22 #region Fields23 Control base
18、Control; /基础控件,即被包围的控件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.MouseU
19、p += new MouseEventHandler(FrameControl_MouseUp);36 37 42 / 鼠标按下事件:44 void FrameControl_MouseDown(object sender, MouseEventArgs e)45 46 47 48 49 / 50 / 鼠标移动事件:51 / 52 void FrameControl_MouseMove(object sender, MouseEventArgs e)53 55 56 57 / 58 / 鼠标弹起事件:59 / 60 void FrameControl_MouseUp(object sender
20、, MouseEventArgs e)61 62 64 #endregion65 66 做完这些准备工作后,将到了主要的部分,就是给控件画边框。整个边框分为三个部分:四边框(用来设置可视区域与区域)+四条虚线(只用来显示)+八个小圆圈(用来斜角拖拉)。所以要建立三个字段,用来分别保存这个数据。 Rectangle smallRects = new Rectangle8;/边框中的八个小圆圈 Rectangle sideRects = new Rectangle4;/四条边框,用来做响应区域 Point linePoints = new Point5;/四条边,用于画虚线接着就是创建用户控件的可
21、视区域,和上面的三个变量数值。(以下计算位置的代码,有兴趣的人可以研究下,没有的就直接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;1
22、1 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()25 /左上26 smallRects0 = new Rectangle(new Point(0, 0), square);27 /右上28 smallRects1 = new Rectangle(new Point(this.Width - square.Width - 1, 0), square);29 /左下30 smallRects2 = new Rectangle(new
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1