c#ovalshape_【原创】C# 实现拖拉控件改变位置与大小(SamWang)(附源代码下载)

前言:

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

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

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

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

一、技术概述

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

二、功能规划

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

7741043ea606b4aafaad89a3f4cb47f3.png

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

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

三、具体实现

1.拖动控件改变位置

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

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

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

代码如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngDragControl

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Windows.Forms;5 usingSystem.Drawing;6

7 namespaceDragControl8 {9 public classMoveControl10 {11 #region Constructors

12 publicMoveControl(Control ctrl)13 {14 currentControl =ctrl;15 AddEvents();16 }17 #endregion

18

19 #region Fields

20 private Control currentControl; //传入的控件

21 #endregion

22

23 #region Properties

24

25 #endregion

26

27 #region Methods

28 ///

29 ///挂载事件30 ///

31 private voidAddEvents()32 {33 currentControl.MouseClick += newMouseEventHandler(MouseClick);34 currentControl.MouseDown += newMouseEventHandler(MouseDown);35 currentControl.MouseMove += newMouseEventHandler(MouseMove);36 currentControl.MouseUp += newMouseEventHandler(MouseUp);37 }38 #endregion

39

40 #region Events

41 ///

42 ///鼠标单击事件:用来显示边框43 ///

44 ///

45 ///

46 void MouseClick(objectsender, MouseEventArgs e)47 {48 }49

50 ///

51 ///鼠标按下事件:记录当前鼠标相对窗体的坐标52 ///

53 void MouseDown(objectsender, MouseEventArgs e)54 {55

56 }57

58 ///

59 ///鼠标移动事件:让控件跟着鼠标移动60 ///

61 void MouseMove(objectsender, MouseEventArgs e)62 {63 }64

65 ///

66 ///鼠标弹起事件:让自定义的边框出现67 ///

68 void MouseUp(objectsender, MouseEventArgs e)69 {70 }71 #endregion

72 }73 }

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

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

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

private Point pPoint; //上个鼠标坐标

private Point cPoint; //当前鼠标坐标

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

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

1 ///

2 ///鼠标单击事件:用来显示边框3 ///

4 void MouseClick(objectsender, MouseEventArgs e)5 {6 pPoint =Cursor.Position;7 }

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

1 ///

2 ///鼠标移动事件:让控件跟着鼠标移动3 ///

4 void MouseMove(objectsender, MouseEventArgs e)5 {6 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll7 //当鼠标左键按下时才触发

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的完整代码如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngMoveControl

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Windows.Forms;5 usingSystem.Drawing;6

7 namespaceDragControl8 {9 public classMoveControl10 {11 #region Constructors

12 publicMoveControl(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 #endregion

24

25 #region Properties

26

27 #endregion

28

29 #region Methods

30 ///

31 ///挂载事件32 ///

33 private voidAddEvents()34 {35 currentControl.MouseDown += newMouseEventHandler(MouseDown);36 currentControl.MouseMove += newMouseEventHandler(MouseMove);37 currentControl.MouseUp += newMouseEventHandler(MouseUp);38 }39

40 ///

41 ///绘制拖拉时的黑色边框42 ///

43 public static voidDrawDragBound(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(newPen(Color.Black), ps);52 }53 #endregion

54

55 #region Events

56 ///

57 ///鼠标按下事件:记录当前鼠标相对窗体的坐标58 ///

59 void MouseDown(objectsender, MouseEventArgs e)60 {61 pPoint =Cursor.Position;62 }63

64 ///

65 ///鼠标移动事件:让控件跟着鼠标移动66 ///

67 void MouseMove(objectsender, 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(objectsender, MouseEventArgs e)86 {87 this.currentControl.Refresh();88 }89 #endregion

90 }91 }

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

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

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

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

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

1 ///

2 ///绘制拖拉时的黑色边框3 ///

4 public static voidDrawDragBound(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(newPen(Color.Black), ps);13 }14

15

16 ///

17 ///鼠标移动事件:让控件跟着鼠标移动18 ///

19 void MouseMove(objectsender, 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(objectsender, MouseEventArgs e)5 {6 this.currentControl.Refresh();7 }

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

cc77c0b5d7062e8587ec261368fb8afb.png

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

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

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngFrameControl

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.ComponentModel;4 usingSystem.Drawing;5 usingSystem.Data;6 usingSystem.Linq;7 usingSystem.Text;8 usingSystem.Windows.Forms;9

10 namespaceDragControl11 {12 public partial classFrameControl : UserControl13 {14 #region Constructors

15 publicFrameControl(Control ctrl)16 {17 baseControl =ctrl;18 AddEvents();19 }20 #endregion

21

22 #region Fields

23 Control baseControl; //基础控件,即被包围的控件

24 #endregion

25

26 #region Methods

27 ///

28 ///加载事件29 ///

30 private voidAddEvents()31 {32 this.Name = "FrameControl" +baseControl.Name;33 this.MouseDown += newMouseEventHandler(FrameControl_MouseDown);34 this.MouseMove += newMouseEventHandler(FrameControl_MouseMove);35 this.MouseUp += newMouseEventHandler(FrameControl_MouseUp);36 }37

38 #endregion

39

40 #region Events

41 ///

42 ///鼠标按下事件:记录当前鼠标相对窗体的坐标43 ///

44 void FrameControl_MouseDown(objectsender, MouseEventArgs e)45 {46

47 }48

49 ///

50 ///鼠标移动事件:让控件跟着鼠标移动51 ///

52 void FrameControl_MouseMove(objectsender, MouseEventArgs e)53 {54

55 }56

57 ///

58 ///鼠标弹起事件:让自定义的边框出现59 ///

60 void FrameControl_MouseUp(objectsender, MouseEventArgs e)61 {62

63 }64 #endregion

65 }66 }

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

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

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

Rectangle[] smallRects = new Rectangle[8];//边框中的八个小圆圈

Rectangle[] sideRects = new Rectangle[4];//四条边框,用来做响应区域

Point[] linePoints = new Point[5];//四条边,用于画虚线

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

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png创建边框

1 #region 创建边框

2 ///

3 ///建立控件可视区域4 ///

5 private voidCreateBounds()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 = newRectangle(X, Y, Width, Height);13 this.BringToFront();14 SetRectangles();15 //设置可视区域

16 this.Region = newRegion(BuildFrame());17 g = this.CreateGraphics();18 }19

20 ///

21 ///设置定义8个小矩形的范围22 ///

23 voidSetRectangles()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 privateGraphicsPath BuildFrame()63 {64 GraphicsPath path = newGraphicsPath();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 returnpath;79 }80 #endregion

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

1 ///

2 ///绘图3 ///

4 public voidDraw()5 {6 this.BringToFront();7 Pen pen = newPen(Color.Black);8 pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果

9 g.DrawLines(pen, linePoints);//绘制四条边线

10 g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部

11 foreach (Rectangle smallRect insmallRects)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(objectsender, 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的时候再显示。

此时的完整代码如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngMoveControl

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Windows.Forms;5 usingSystem.Drawing;6

7 namespaceDragControl8 {9 public classMoveControl10 {11 #region Constructors

12 publicMoveControl(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 voidAddEvents()35 {36 currentControl.MouseClick += newMouseEventHandler(MouseClick);37 currentControl.MouseDown += newMouseEventHandler(MouseDown);38 currentControl.MouseMove += newMouseEventHandler(MouseMove);39 currentControl.MouseUp += newMouseEventHandler(MouseUp);40 }41

42 ///

43 ///绘制拖拉时的黑色边框44 ///

45 public static voidDrawDragBound(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(newPen(Color.Black), ps);54 }55 #endregion

56

57 #region Events

58 ///

59 ///鼠标单击事件:用来显示边框60 ///

61 ///

62 ///

63 protected void MouseClick(objectsender, 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(objectsender, MouseEventArgs e)77 {78 pPoint =Cursor.Position;79 }80

81 ///

82 ///鼠标移动事件:让控件跟着鼠标移动83 ///

84 void MouseMove(objectsender, MouseEventArgs e)85 {86 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll87 //当鼠标左键按下时才触发

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(objectsender, MouseEventArgs e)104 {105 this.currentControl.Refresh();106 if (fc != null)107 {108 fc.Visible = true;109 fc.Draw();110 }111 }112 #endregion

113 }114 }

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngFrameControl

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.ComponentModel;4 usingSystem.Drawing;5 usingSystem.Data;6 usingSystem.Text;7 usingSystem.Windows.Forms;8 usingSystem.Drawing.Drawing2D;9

10 namespaceDragControl11 {12 public partial classFrameControl : UserControl13 {14 #region Constructors

15 publicFrameControl(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 voidAddEvents()39 {40 this.Name = "FrameControl" +baseControl.Name;41 this.MouseDown += newMouseEventHandler(FrameControl_MouseDown);42 this.MouseMove += newMouseEventHandler(FrameControl_MouseMove);43 this.MouseUp += newMouseEventHandler(FrameControl_MouseUp);44 }45

46 #region 创建边框

47 ///

48 ///建立控件可视区域49 ///

50 private voidCreateBounds()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 = newRectangle(X, Y, Width, Height);58 this.BringToFront();59 SetRectangles();60 //设置可视区域

61 this.Region = newRegion(BuildFrame());62 g = this.CreateGraphics();63 }64

65 ///

66 ///设置定义8个小矩形的范围67 ///

68 voidSetRectangles()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 privateGraphicsPath BuildFrame()108 {109 GraphicsPath path = newGraphicsPath();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 returnpath;124 }125 #endregion

126

127 ///

128 ///绘图129 ///

130 public voidDraw()131 {132 this.BringToFront();133 Pen pen = newPen(Color.Black);134 pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果

135 g.DrawLines(pen, linePoints);//绘制四条边线

136 g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部

137 foreach (Rectangle smallRect insmallRects)138 {139 g.DrawEllipse(Pens.Black, smallRect); //绘制8个小椭圆

140 }141 //g.DrawRectangles(Pens.Black, smallRects);//绘制8个小矩形的黑色边线

142 }143

144 #endregion

145

146 #region Events

147 ///

148 ///鼠标按下事件:记录当前鼠标相对窗体的坐标149 ///

150 void FrameControl_MouseDown(objectsender, MouseEventArgs e)151 {152

153 }154

155 ///

156 ///鼠标移动事件:让控件跟着鼠标移动157 ///

158 void FrameControl_MouseMove(objectsender, MouseEventArgs e)159 {160

161 }162

163 ///

164 ///鼠标弹起事件:让自定义的边框出现165 ///

166 void FrameControl_MouseUp(objectsender, MouseEventArgs e)167 {168

169 }170 #endregion

171 }172 }

测试界面:

5f92ccbb951f707a2b0f13e72987c351.png

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

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

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

1 ///

2 ///鼠标在控件中位置3 ///

4 enumMousePosOnCtrl5 {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, inty)5 {6 Point point = newPoint(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 else

53 {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(objectsender, MouseEventArgs e)5 {6 pPoint =Cursor.Position;7 }8

9 ///

10 ///鼠标移动事件:让控件跟着鼠标移动11 ///

12 void FrameControl_MouseMove(objectsender, MouseEventArgs e)13 {14 if (e.Button ==MouseButtons.Left)15 {16 this.Visible = false;17 MoveControl.DrawDragBound(baseControl);18 ControlMove();19 }20 else

21 {22 this.Visible = true;23 SetCursorShape(e.X, e.Y); //更新鼠标指针样式

24 }25 }26

27 ///

28 ///鼠标弹起事件:让自定义的边框出现29 ///

30 void FrameControl_MouseUp(objectsender, 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 voidControlMove()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 caseMousePosOnCtrl.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 caseMousePosOnCtrl.BOTTOM:24 if (baseControl.Height + y >MinHeight)25 {26 baseControl.Height +=y;27 }28 else

29 {30 baseControl.Height =MinHeight;31 }32 break;33 caseMousePosOnCtrl.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 caseMousePosOnCtrl.RIGHT:47 if (baseControl.Width + x >MinWidth)48 {49 baseControl.Width +=x;50 }51 else

52 {53 baseControl.Width =MinWidth;54 }55 break;56 caseMousePosOnCtrl.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 caseMousePosOnCtrl.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 caseMousePosOnCtrl.BOTTOMLEFT:99 if (baseControl.Height + y >MinHeight)100 {101 baseControl.Height +=y;102 }103 else

104 {105 baseControl.Height =MinHeight;106 }107 if (baseControl.Width - x >MinWidth)108 {109 baseControl.Left +=x;110 baseControl.Width -=x;111 }112 else

113 {114 baseControl.Left -= MinWidth -baseControl.Width;115 baseControl.Width =MinWidth;116 }117 break;118 caseMousePosOnCtrl.BOTTOMRIGHT:119 if (baseControl.Height + y >MinHeight)120 {121 baseControl.Height +=y;122 }123 else

124 {125 baseControl.Height =MinHeight;126 }127 if (baseControl.Width + x >MinWidth)128 {129 baseControl.Width +=x;130 }131 else

132 {133 baseControl.Width =MinWidth;134 }135 break;136

137 }138 pPoint =Cursor.Position;139 }

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

完成代码如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngMoveControl

1 /******************************************************************2 * 创 建 人: SamWang3 * 创建时间: 2012-5-10 16:064 * 描 述:5 * 移动控件但不改变大小6 * 原 理:7 * 版 本: V1.08 * 环 境: VS20109 ******************************************************************/

10 usingSystem;11 usingSystem.Collections.Generic;12 usingSystem.Linq;13 usingSystem.Text;14 usingSystem.Windows.Forms;15 usingSystem.Drawing;16

17 namespaceDragControl18 {19 public classMoveControl20 {21 #region Constructors

22 publicMoveControl(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 voidAddEvents()45 {46 currentControl.MouseClick += newMouseEventHandler(MouseClick);47 currentControl.MouseDown += newMouseEventHandler(MouseDown);48 currentControl.MouseMove += newMouseEventHandler(MouseMove);49 currentControl.MouseUp += newMouseEventHandler(MouseUp);50 }51

52 ///

53 ///绘制拖拉时的黑色边框54 ///

55 public static voidDrawDragBound(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(newPen(Color.Black), ps);64 }65

66 #endregion

67

68 #region Events

69 ///

70 ///鼠标单击事件:用来显示边框71 ///

72 ///

73 ///

74 protected void MouseClick(objectsender, 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(objectsender, MouseEventArgs e)88 {89 pPoint =Cursor.Position;90 }91

92 ///

93 ///鼠标移动事件:让控件跟着鼠标移动94 ///

95 void MouseMove(objectsender, MouseEventArgs e)96 {97 Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll98 //当鼠标左键按下时才触发

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(objectsender, MouseEventArgs e)115 {116 this.currentControl.Refresh();117 if (fc != null)118 {119 fc.Visible = true;120 fc.Draw();121 }122 }123 #endregion

124 }125 }

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngFrameControl

1 /******************************************************************2 * 创 建 人: SamWang3 * 创建时间: 2012-5-10 17:004 * 描 述:5 * 在控件外部加上边框,用于拖拉,以改变内部控件的大小6 * 原 理:7 * 版 本: V1.08 * 环 境: VS20109 ******************************************************************/

10 usingSystem;11 usingSystem.Collections.Generic;12 usingSystem.Text;13 usingSystem.Windows.Forms;14 usingSystem.Drawing;15 usingSystem.Drawing.Drawing2D;16

17 namespaceDragControl18 {19 public classFrameControl : UserControl20 {21 #region Constructors

22 ///

23 ///构造函数24 ///

25 publicFrameControl(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 privateMousePosOnCtrl mpoc;47 #endregion

48

49 #region Properties

50 ///

51 ///鼠标在控件中位置52 ///

53 enumMousePosOnCtrl54 {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 voidAddEvents()72 {73 this.Name = "FrameControl" +baseControl.Name;74 this.MouseDown += newMouseEventHandler(FrameControl_MouseDown);75 this.MouseMove += newMouseEventHandler(FrameControl_MouseMove);76 this.MouseUp += newMouseEventHandler(FrameControl_MouseUp);77 }78

79 #region 创建边框

80 ///

81 ///建立控件可视区域82 ///

83 private voidCreateBounds()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 = newRectangle(X, Y, Width, Height);91 this.BringToFront();92 SetRectangles();93 //设置可视区域

94 this.Region = newRegion(BuildFrame());95 g = this.CreateGraphics();96 }97

98 ///

99 ///设置定义8个小矩形的范围100 ///

101 voidSetRectangles()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 privateGraphicsPath BuildFrame()141 {142 GraphicsPath path = newGraphicsPath();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 returnpath;157 }158 #endregion

159

160 ///

161 ///绘图162 ///

163 public voidDraw()164 {165 this.BringToFront();166 //g.FillRectangles(Brushes.LightGray, sideRects);//填充四条边框的内部

167 Pen pen = newPen(Color.Black);168 pen.DashStyle = DashStyle.Dot;//设置为虚线,用虚线画四边,模拟微软效果

169 g.DrawLines(pen, linePoints);//绘制四条边线

170 g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部

171 foreach (Rectangle smallRect insmallRects)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, inty)182 {183 Point point = newPoint(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 else

230 {231 Cursor.Current =Cursors.Arrow;232 }233 return true;234 }235

236 ///

237 ///控件移动238 ///

239 private voidControlMove()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 caseMousePosOnCtrl.TOP:247 if (baseControl.Height - y >MinHeight)248 {249 baseControl.Top +=y;250 baseControl.Height -=y;251 }252 else

253 {254 baseControl.Top -= MinHeight -baseControl.Height;255 baseControl.Height =MinHeight;256 }257 break;258 caseMousePosOnCtrl.BOTTOM:259 if (baseControl.Height + y >MinHeight)260 {261 baseControl.Height +=y;262 }263 else

264 {265 baseControl.Height =MinHeight;266 }267 break;268 caseMousePosOnCtrl.LEFT:269 if (baseControl.Width - x >MinWidth)270 {271 baseControl.Left +=x;272 baseControl.Width -=x;273 }274 else

275 {276 baseControl.Left -= MinWidth -baseControl.Width;277 baseControl.Width =MinWidth;278 }279

280 break;281 caseMousePosOnCtrl.RIGHT:282 if (baseControl.Width + x >MinWidth)283 {284 baseControl.Width +=x;285 }286 else

287 {288 baseControl.Width =MinWidth;289 }290 break;291 caseMousePosOnCtrl.TOPLEFT:292 if (baseControl.Height - y >MinHeight)293 {294 baseControl.Top +=y;295 baseControl.Height -=y;296 }297 else

298 {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 else

308 {309 baseControl.Left -= MinWidth -baseControl.Width;310 baseControl.Width =MinWidth;311 }312 break;313 caseMousePosOnCtrl.TOPRIGHT:314 if (baseControl.Height - y >MinHeight)315 {316 baseControl.Top +=y;317 baseControl.Height -=y;318 }319 else

320 {321 baseControl.Top -= MinHeight -baseControl.Height;322 baseControl.Height =MinHeight;323 }324 if (baseControl.Width + x >MinWidth)325 {326 baseControl.Width +=x;327 }328 else

329 {330 baseControl.Width =MinWidth;331 }332 break;333 caseMousePosOnCtrl.BOTTOMLEFT:334 if (baseControl.Height + y >MinHeight)335 {336 baseControl.Height +=y;337 }338 else

339 {340 baseControl.Height =MinHeight;341 }342 if (baseControl.Width - x >MinWidth)343 {344 baseControl.Left +=x;345 baseControl.Width -=x;346 }347 else

348 {349 baseControl.Left -= MinWidth -baseControl.Width;350 baseControl.Width =MinWidth;351 }352 break;353 caseMousePosOnCtrl.BOTTOMRIGHT:354 if (baseControl.Height + y >MinHeight)355 {356 baseControl.Height +=y;357 }358 else

359 {360 baseControl.Height =MinHeight;361 }362 if (baseControl.Width + x >MinWidth)363 {364 baseControl.Width +=x;365 }366 else

367 {368 baseControl.Width =MinWidth;369 }370 break;371

372 }373 pPoint =Cursor.Position;374 }375

376 #endregion

377

378 #region Events

379 ///

380 ///鼠标按下事件:记录当前鼠标相对窗体的坐标381 ///

382 void FrameControl_MouseDown(objectsender, MouseEventArgs e)383 {384 pPoint =Cursor.Position;385 }386

387 ///

388 ///鼠标移动事件:让控件跟着鼠标移动389 ///

390 void FrameControl_MouseMove(objectsender, MouseEventArgs e)391 {392 if (e.Button ==MouseButtons.Left)393 {394 this.Visible = false;395 MoveControl.DrawDragBound(baseControl);396 ControlMove();397 }398 else

399 {400 this.Visible = true;401 SetCursorShape(e.X, e.Y); //更新鼠标指针样式

402 }403 }404

405 ///

406 ///鼠标弹起事件:让自定义的边框出现407 ///

408 void FrameControl_MouseUp(objectsender, MouseEventArgs e)409 {410 this.baseControl.Refresh(); //刷掉黑色边框

411 this.Visible = true;412 CreateBounds();413 Draw();414 }415 #endregion

416 }417 }

四、遗留问题

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

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

五、附源代码下载

SamWang

2012-05-14

作者:SamWang

出处:http://wangshenhe.cnblogs.com/

本文版权归作者和博客园共有,欢迎围观转载。转载时请您务必在文章明显位置给出原文链接,谢谢您的合作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jmeter提取mysql数据_通过jmeter读取数据库数据,并取值作为请求的入参

为提升测试技能,督促自己学习。故写了这篇文章。测试小白一枚,最近感觉达到了自己认为的瓶颈期。总是有想法,想突破,但是无从入手。工具类用过fiddler、jmeter、charels、postman..大体接口测试工具,均多多少少使用过。…

如何快速上手mysql_mysql快速上手3

上一章给大家说的是数据库的视图,存储过程等等操作,这章主要讲索引,以及索引注意事项,如果想看前面的文章,url如下:索引简介索引是对数据库表中一个或多个列(例如,employee 表的姓名 (name) 列)…

c mysql 免安装版_MySQL5.6免安装版环境配置图文教程

MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行。但是官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的。很多人下了zip格式的解压发现没有setup.exe,面对一堆文件一头雾水,不知如何安装。下面小编将介…

MDL锁导致mysql夯住_MySQL MetaData Lock 案例分享

前言:今天开发童鞋遇到一个奇怪的问题,在测试环境里面执行drop database dbname发现一直夯住不动,等了很久也没有执行,于是问题就到我这里了一、什么是MetaData Lock?MetaData Lock即元数据锁,在数据库中元…

docker 分布式管理群集_Coolpy7分布式物联网MQTT集群搭建

Coolpy7分布式技术,支持多个Coolpy7 Core提供跨数据中心(多活)模式组建群集,支持群集零手动维护(基于Gossip分布式协议作为群集节点状态维护)。Coolpy7从版本号V7.3.2.3开始支持本功能。请到Coolpy7之github项目release下载相关版本https://github.com/C…

vue 数值 拼接字符串_【Vue原理】Compile - 白话版

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 【2.5.17】如果你觉得排版难看,请点击 下面链…

gpio驱动蜂鸣器出现破音_五款蜂鸣器驱动电路原理图

蜂鸣器驱动电路图一:典型的蜂鸣器驱动电路,蜂鸣器驱动电路一般包含:一个三极管、一个蜂鸣器、一个续流二极管、一个滤波电容。1、蜂鸣器:发声元件,在其两端施加直流电压(有源蜂鸣器)或者方波(无源蜂鸣器)就可以发声&am…

mysql 多项式_mysql主从复制原理及实现

一.主从复制原理利用MySQL提供的Replication,其实就是Slave从Master获取Binary log文件,然后再本地镜像的执行日志中记录的操作。由于主从复制的过程是异步的,因此Slave和Master之间的数据有可能存在延迟的现象,此时只能保证数据最…

idea创建web项目运行报404错误_使用IDEA新建Web工程启动报404的错误

新换了一个项目组被人吐槽配置文件都能写错,所以打算从头开始一步步搭建一个项目,包含ssm基础框架、mongodb工具类、redis工具类、jsf配置、log配置等今天先来搭建一个web工程。工程搭建好运行时发现404我们都知道,一般404都是由于请求资源的…

java md2_GitHub - edzjx/Md2Crypto

此项目来源一个字谜解体过程一个程序猿在自己的微信公众号里出了一个字谜。其中用到了MD2加密算法,这是各很古老的加密算法。从网上搜到作者92年发布的C代码还能正常执行。此项目介绍解题过程,和使用C,C#,Java,Python3来测试代码。文章结构破…

java stringbuffer原理_深入理解Java:String

在讲解String之前,我们先了解一下Java的内存结构。一、Java内存模型按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。JVM主要管理两种类型内存:堆和非堆,堆…

java dubbo jsf_cubelink

cubelink概要设计[TOC]1. 撰写记录更新时间内容作者2017-08-23 08:39:31撰写参数回调章节内容林斌2017-08-22 21:26:52增加了异步响应和异步回调章节林斌2017-08-22 14:36:36确定文档结构和大致框架林斌2. 设计目标设计一个具备治理,监控,服务发现能力的…

python 的案例实战_python案例实战之一

分析思路:1、明确分析目标;2、导入库、导入数据;3、简单查看下数据行列、整体情况;4、数据清洗;5、确定维度和指标;6、分析并作图1、查看整体数据情况1.1引入使用的库import numpy as npimport pandas as p…

java数据结构期末复习_java数据结构复习02

1.递归问题1.1计算阶乘packageinterview.recursion;importjava.util.Scanner;public classFact {public static voidmain(String[] args) {System.out.println("请输入n的值:");Scanner in newScanner(System.in);int n in.nextInt();int num fact(n);Sys…

java中methods方法_java中Class.getMethod方法

Method Class.getMethod(String name, Class>... parameterTypes)的作用是获得对象所声明的公开方法该方法的第一个参数name是要获得方法的名字,第二个参数parameterTypes是按声明顺序标识该方法形参类型。person.getClass().getMethod("Speak", null)…

centos6 yum快速安装mysql_centos6.10 yum安装mysql 5.6-Go语言中文社区

一、检查系统是否安装其他版本的MYSQL数据#yum list installed | grep mysql#yum -y remove 文件名二、安装及配置# wget http://repo.mysql.com/mysql-community-release-el6-5.noarch.rpm# rpm -ivh mysql-community-release-el6-5.noarch.rpm# yum repolist all | grep mysq…

二叉树两节点距离java,求二叉树中两个节点的最远距离

问题定义如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数。写一个程序求一棵二叉树中相距最远的两个节点之间的距离。计算一个二叉树的最大距离有两个情况:情况A: 路径经过左子树的最深节…

php cli 编程,php-cli下编程如何分层架构、面向对象、统一入口文件?

以往写cli下运行的业务或者测试代码,总是新建文件,面向过程编写代码。几次之后,cli目录下好多文件,即便勉强在一个cli测试文件中写了一个类,也是让其中的一个方法自启动,要测试别的方法,总是要修…

php中gd为什么是乱码的,php gd库中文乱码怎么解决?

php gd库中文乱码怎么解决?,中文,乱码,字符,选项,字体php gd库中文乱码怎么解决?易采站长站,站长之家为您整理了php gd库中文乱码怎么解决?的相关内容。解决方法:1、网站整站使用UTF8编码,如果已使用GB2312…

php实现飘窗,JS实现网站图片飘窗效果,JavaScript悬浮广告(附详细代码)

原标题:JS实现网站图片飘窗效果,JavaScript悬浮广告(附详细代码)JS实现网站图片飘窗效果,Java悬浮广告,郑州SEO提供以下代码,仅供参考:飘窗效果-丁光辉博客(www.dingguanghui.com)*{margin:0px;padding:0px…