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) 列)…

mysql blob 好处_MySQL中的BLOB类型

一、概念:BLOB (binary large object)二进制大对象,是一个可以存储二进制文件的容器。在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的…

mysql group by null_MySQL无GROUP BY直接HAVING返回空的问题分析

有一张表,id是主键,这样的写法可以返回一条记录:复制代码 代码如下:“SELECT * FROM t HAVING idMIN(id);”但是只是把MIN换成MAX,这样返回就是空了:复制代码 代码如下:“SELECT * FROM t HAVING idMAX(id);”这是为什…

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

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

python士兵突击_想自学Python进入该行业成为一名自己一直以来就很羡慕和钦佩的程序员,过来人的你有什么想分享的吗?...

多说无益就是干,学习编程也这样。我们下面主要通过以下三个步骤给出建议:1.确定目标(成为一个能干活的Python需要掌握哪些技能)。我们可以通过市面上对于Python工程师对招聘要求,去分析,具体需要掌握哪些内容。这个详细内容可以在…

启动项 mysql命令大全_mysql常用命令

一、登录mysql数据库1、连接本地mysql数据库,默认端口为3306#mysql –u root –p 123456 //-u:指定用户 -p:指定与用户对应的密码2、通过IP和端口连接远程mysql服务器#mysql –u root –p 123456 –h 192.168.100.1 –P 3306二、数据库操作语句1、显示所…

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

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

ubuntu16 黑主题_给Ubuntu 8.10安装超炫酷黑色新主题

Linux系统的Netbook定做了一套漂亮的界面,名称叫做 HP Mini 1000 Mi Edition。这套界面是基于 Ubuntu 8.04 Hardy Heron的,平常我们熟悉的Ubuntu程序等都可以在这里都使用.不过让 Mi Edition 脱颖而出的是这看起来根本不像是我们平时看过的Ubuntu界面, 看上去倒像媒体中心。这个…

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…

php和mysql的实践报告_PHP+MySQL项目开发与实践

前言部分基础篇任务一PHP基础知识简介1.1静态网页与动态网页的工作原理1.1.1静态网页与工作原理1.1.2动态网页与工作原理1.2初识PHP1.3习题任务二PHP程序的运行环境搭建2.1配置Apache服务器2.1.1安装Apache服务器2.1.2Apache服务器安装过程中的问题及解决方案2.1.3Apache主目录…

mediumint 在mysql 中是什么类型_mysql中bigint、int、mediumint、smallint 和 tinyint的取值范围...

mysql数据库设计,其中,对于数据性能优化,字段类型考虑很重要,搜集了些资料,整理分享出来,这篇为有关mysql整型bigint、int、mediumint、smallint 和 tinyint的语法介绍,如下:1、bigi…

mysql备份还原数据库操作系统_mysql 命令行备份还原数据库操作

一 备份操作1.备份全部数据库mysqldump -uroot -p --all databases > aa.sql2.备份某个数据库并压缩mysqldump -uroot -p databasename |gzip > aa.sql.gz3 .备份单个表mysqldump -uroot -p -table dbname tbname1 tbname2 >aa.sql4.同时备份多个数据库mysqldump -ur…

python表示当前对象_对象操作

[TOC]# 对象操作## help:返回对象的帮助信息~~~>>> help(str)Help on class str in module builtins:class str(object)| str(object) -> str| str(bytes_or_buffer[, encoding[, errors]]) -> str|| Create a new string object from the given object. If enc…

中国大学慕课python答案第七章_中国大学慕课mooc用Python玩转数据章节答案

嵌体来源A.嵌入牙冠内的修复体 B.没有覆盖前牙唇面或后牙颊面的部分冠修复体艺术不是象牙塔里的_____ ,所谓的“为艺术而艺术”,说到底不过是唯美主义_____的志向。自古以来,艺小轿车的速度比卡车的速度每小时快6千米,小轿车和卡车…

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

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

python迭代器是什么百度百科,python迭代器的接口是什么?

What are the required methods for defining an iterator? For instance, on the following Infinity iterator, are its methods sufficient? Are there other standard or de factor standard methods that define an iterator?class Infinity(object):def __init__(self…

python逻辑表达式3+45and_python入门到精通(一)| python基础语法与各种运算符的使用...

一、python中的基础语法1、输入语句 input格式:变量input(“输入提示信息”)功能:从键盘上输入一行文本信息到变量中,可以强转为各种数据类型。案例: xinput(“您的个人基本信息”)注意点:只能接受一行信息2 input语句…