C# 实现拖拉控件改变位置与大小SamWang文档格式.docx
《C# 实现拖拉控件改变位置与大小SamWang文档格式.docx》由会员分享,可在线阅读,更多相关《C# 实现拖拉控件改变位置与大小SamWang文档格式.docx(56页珍藏版)》请在冰豆网上搜索。
11#regionConstructors
12publicMoveControl(Controlctrl)
13{
14currentControl=ctrl;
15AddEvents();
16}
17#endregion
18
19#regionFields
20privateControlcurrentControl;
//传入的控件
21#endregion
22
23#regionProperties
24
25#endregion
26
27#regionMethods
28///<
summary>
29///挂载事件
30///<
/summary>
31privatevoidAddEvents()
32{
33currentControl.MouseClick+=newMouseEventHandler(MouseClick);
34currentControl.MouseDown+=newMouseEventHandler(MouseDown);
35currentControl.MouseMove+=newMouseEventHandler(MouseMove);
36currentControl.MouseUp+=newMouseEventHandler(MouseUp);
37}
38#endregion
39
40#regionEvents
41///<
42///鼠标单击事件:
用来显示边框
43///<
44///<
paramname="
sender"
>
<
/param>
45///<
e"
46voidMouseClick(objectsender,MouseEventArgse)
47{
48}
49
50///<
51///鼠标按下事件:
记录当前鼠标相对窗体的坐标
52///<
53voidMouseDown(objectsender,MouseEventArgse)
54{
55
56}
57
58///<
59///鼠标移动事件:
让控件跟着鼠标移动
60///<
61voidMouseMove(objectsender,MouseEventArgse)
62{
63}
64
65///<
66///鼠标弹起事件:
让自定义的边框出现
67///<
68voidMouseUp(objectsender,MouseEventArgse)
69{
70}
71#endregion
72}
73}
接着我们需要实现MouseDown、MouseMove、MouseUp三个事件。
不过在此之前,我们必须要弄清楚,移动即表示坐标的改变,所以必定要有个起始坐标和终点坐标。
所以我们在MoveControl类中加入两个字段。
privatePointpPoint;
//上个鼠标坐标
privatePointcPoint;
//当前鼠标坐标
而且在开始拖动之前,我们肯定需要先单击一次控件。
在MouseDown时获取当前光标的位置,保存到pPoint中。
(此处用Cursor获得坐标的好处,就是忽略掉容器的麻烦问题)
1///<
2///鼠标单击事件:
3///<
4voidMouseClick(objectsender,MouseEventArgse)
5{
6pPoint=Cursor.Position;
7}
接着便实现MouseMove的事件,当鼠标左键按下时,接着移动鼠标后,继续鼠标移动后的坐标,然后与MouseDown时记下的坐标相减,就得到鼠标的位移值,接着控件的Location加上该位移值即可,然后更新pPoint。
1///<
2///鼠标移动事件:
3///<
4voidMouseMove(objectsender,MouseEventArgse)
5{
6Cursor.Current=Cursors.SizeAll;
//当鼠标处于控件内部时,显示光标样式为SizeAll
7//当鼠标左键按下时才触发
8if(e.Button==MouseButtons.Left)
9{
10cPoint=Cursor.Position;
//获得当前鼠标位置
11intx=cPoint.X-pPoint.X;
12inty=cPoint.Y-pPoint.Y;
13currentControl.Location=newPoint(currentControl.Location.X+x,currentControl.Location.Y+y);
14pPoint=cPoint;
15}
由于此时还没涉及到边框,所以MouseUp暂时不用处理。
至此拖动的基本功能已经实现!
目前MoveControl的完整代码如下:
MoveControl
21privatePointpPoint;
22privatePointcPoint;
23#endregion
25#regionProperties
27#endregion
28
29#regionMethods
31///挂载事件
32///<
33privatevoidAddEvents()
34{
35currentControl.MouseDown+=newMouseEventHandler(MouseDown);
36currentControl.MouseMove+=newMouseEventHandler(MouseMove);
37currentControl.MouseUp+=newMouseEventHandler(MouseUp);
38}
40///<
41///绘制拖拉时的黑色边框
42///<
43publicstaticvoidDrawDragBound(Controlctrl)
44{
45ctrl.Refresh();
46Graphicsg=ctrl.CreateGraphics();
47intwidth=ctrl.Width;
48intheight=ctrl.Height;
49Point[]ps=newPoint[5]{newPoint(0,0),newPoint(width-1,0),
50newPoint(width-1,height-1),newPoint(0,height-1),newPoint(0,0)};
51g.DrawLines(newPen(Color.Black),ps);
52}
53#endregion
54
55#regionEvents
56///<
57///鼠标按下事件:
59voidMouseDown(objectsender,MouseEventArgse)
60{
61pPoint=Cursor.Position;
62}
63
64///<
65///鼠标移动事件:
66///<
67voidMouseMove(objectsender,MouseEventArgse)
68{
69Cursor.Current=Cursors.SizeAll;
70//当鼠标左键按下时才触发
71if(e.Button==MouseButtons.Left)
72{
73MoveControl.DrawDragBound(this.currentControl);
74cPoint=Cursor.Position;
75intx=cPoint.X-pPoint.X;
76inty=cPoint.Y-pPoint.Y;
77currentControl.Location=newPoint(currentControl.Location.X+x,currentControl.Location.Y+y);
78pPoint=cPoint;
79}
80}
81
82///<
83///鼠标弹起事件:
84///<
85voidMouseUp(objectsender,MouseEventArgse)
86{
87this.currentControl.Refresh();
88}
89#endregion
90}
91}
下面我们来测试下拖动的功能。
创建一个Form窗体,可以再界面上添加你要测试的控件类型,此处我只用TextBox左下测试。
在Load的中添加以下代码,将Form中的所有控件挂载上拖拉功能。
1privatevoidForm1_Load(objectsender,EventArgse)
2{
3foreach(Controlctrlinthis.Controls)
4{
5newMoveControl(ctrl);
6}
此时,有心人可能会发现VS中拖动控件时,将会出现黑色边框,而处于没有。
这也很简单,我们在MouseMove时加上如下代码即可。
2///绘制拖拉时的黑色边框
4publicstaticvoidDrawDragBound(Controlctrl)
6ctrl.Refresh();
7Graphicsg=ctrl.CreateGraphics();
8intwidth=ctrl.Width;
9intheight=ctrl.Height;
10Point[]ps=newPoint[5]{newPoint(0,0),newPoint(width-1,0),
11newPoint(width-1,height-1),newPoint(0,height-1),newPoint(0,0)};
12g.DrawLines(newPen(Color.Black),ps);
13}
14
15
16///<
17///鼠标移动事件:
18///<
19voidMouseMove(objectsender,MouseEventArgse)
20{
21Cursor.Current=Cursors.SizeAll;
22//当鼠标左键按下时才触发
23if(e.Button==MouseButtons.Left)
24{
25MoveControl.DrawDragBound(this.currentControl);
26cPoint=Cursor.Position;
27intx=cPoint.X-pPoint.X;
28inty=cPoint.Y-pPoint.Y;
29currentControl.Location=newPoint(currentControl.Location.X+x,currentControl.Location.Y+y);
30pPoint=cPoint;
31}
32}
同时要在MoveUp的时候,刷新一下自己,让黑色边框消失掉!
2///鼠标弹起事件:
4voidMouseUp(objectsender,MouseEventArgse)
6this.currentControl.Refresh();
接着用没有边框的控件测试下就会很明显。
如下图所示:
2.通过边框拖拉控件改变大小
此处的主要思路为:
点击控件的时候,创建一个自定义的用户控件,该用户控件响应区域就是传入控件的边框区域,同时给它画上虚线与8个小圆圈。
第一、创建用户控件--FrameControl(边框控件),然后增加一个字段用来保存传入的控件,还有加载事件,此处类同前面的MoveControl。
FrameControl
3usingSystem.ComponentModel;
4usingSystem.Drawing;
5usingSystem.Data;
6usingSystem.Linq;
7usingSystem.Text;
8usingSystem.Windows.Forms;
9
10namespaceDragControl
11{
12publicpartialclassFrameControl:
UserControl
14#regionConstructors
15publicFrameControl(Controlctrl)
16{
17baseControl=ctrl;
18AddEvents();
19}
20#endregion
21
22#regionFields
23ControlbaseControl;
//基础控件,即被包围的控件
24#endregion
25
26#regionMethods
27///<
28///加载事件
29///<
30privatevoidAddEvents()
31{
32this.Name="
FrameControl"
+baseControl.Name;
33this.MouseDown+=newMouseEventHandler(FrameControl_MouseDown);
34this.MouseMove+=newMouseEventHandler(FrameControl_MouseMove);
35this.MouseUp+=newMouseEventHandler(FrameControl_MouseUp);
36}
37
42///鼠标按下事件:
44voidFrameControl_MouseDown(objectsender,MouseEventArgse)
45{
46
47}
48
49///<
50///鼠标移动事件:
51///<
52voidFrameControl_MouseMove(objectsender,MouseEventArgse)
53{
55}
56
57///<
58///鼠标弹起事件:
59///<
60voidFrameControl_MouseUp(objectsender,MouseEventArgse)
61{
62
64#endregion
65}
66}
做完这些准备工作后,将到了主要的部分,就是给控件画边框。
整个边框分为三个部分:
四边框(用来设置可视区域与区域)+四条虚线(只用来显示)+八个小圆圈(用来斜角拖拉)。
所以要建立三个字段,用来分别保存这个数据。
Rectangle[]smallRects=newRectangle[8];
//边框中的八个小圆圈
Rectangle[]sideRects=newRectangle[4];
//四条边框,用来做响应区域
Point[]linePoints=newPoint[5];
//四条边,用于画虚线
接着就是创建用户控件的可视区域,和上面的三个变量数值。
(以下计算位置的代码,有兴趣的人可以研究下,没有的就直接Copy)
创建边框
1#region创建边框
2///<
3///建立控件可视区域
4///<
5privatevoidCreateBounds()
6{
7//创建边界
8intX=baseControl.Bounds.X-square.Width-1;
9intY=baseControl.Bounds.Y-square.Height-1;
10intHeight=baseControl.Bounds.Height+(square.Height*2)+2;
11intWidth=baseControl.Bounds.Width+(square.Width*2)+2;
12this.Bounds=newRectangle(X,Y,Width,Height);
13this.BringToFront();
14SetRectangles();
15//设置可视区域
16this.Region=newRegion(BuildFrame());
17g=this.CreateGraphics();
18}
19
20///<
21///设置定义8个小矩形的范围
22///<
23voidSetRectangles()
25//左上
26smallRects[0]=newRectangle(newPoint(0,0),square);
27//右上
28smallRects[1]=newRectangle(newPoint(this.Width-square.Width-1,0),square);
29//左下
30smallRects[2]=newRectangle(new