C# 实现拖拉控件改变位置与大小SamWang.docx
- 文档编号:8917469
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:56
- 大小:62.98KB
C# 实现拖拉控件改变位置与大小SamWang.docx
《C# 实现拖拉控件改变位置与大小SamWang.docx》由会员分享,可在线阅读,更多相关《C# 实现拖拉控件改变位置与大小SamWang.docx(56页珍藏版)》请在冰豆网上搜索。
C#实现拖拉控件改变位置与大小SamWang
前言:
很多时候我们需要在运行时,动态地改变控件的位置以及大小,以获得更好的布局。
比如说实际项目中的可自定义的报表、可自定义的单据等诸如此类。
它们有个特点就是允许客户或者二次开发人员设计它们需要的界面设置功能。
本人以前也做过可自定义系统,包括界面和功能,主要为了减少开发人员的工作量以及程序的灵活性和健壮性。
本篇主要讨论下,在运行时如何实现拖拉控件,达到改变控件位置与大小。
功能将模拟VS设计界面时的拖拉功能。
(本篇暂不涉及多控件同时操作)
一、技术概述
其实实现运行时控件的拖拉并不难,主要是改变控件的Location与Size即可。
动态调整时再捕获MouseDown、MouseMove及MouseUp事件来实时修改上述两个属性就可以实现。
二、功能规划
在此之前,我们先来看下.net设计界面,一旦选中某个控件时,将会出现如下图的边框:
之后就可以通过拖拉出现的边框改变其大小。
而改变控件的位置,实际上是当鼠标点击在控件内部拖动时实现的。
所有本例也将功能分为两个部分实现,分别为控件内部拖动改变位置与控件边框拖拉改变大小。
三、具体实现
1.拖动控件改变位置
首先,新建一个项目,然后添加一个类,取名叫MoveControl,该类用来给控件挂载事件实现拖动。
接着在该类中添加字段currentControl,用来保存需要操作的控件,即通过构造函数传递的控件。
接着创建一方法--AddEvents,用来给当前的控件挂载事件。
代码如下:
DragControl
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4usingSystem.Windows.Forms;
5usingSystem.Drawing;
6
7namespaceDragControl
8{
9publicclassMoveControl
10{
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///
29///挂载事件
30///
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///
45///
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}
16}
由于此时还没涉及到边框,所以MouseUp暂时不用处理。
至此拖动的基本功能已经实现!
目前MoveControl的完整代码如下:
MoveControl
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4usingSystem.Windows.Forms;
5usingSystem.Drawing;
6
7namespaceDragControl
8{
9publicclassMoveControl
10{
11#regionConstructors
12publicMoveControl(Controlctrl)
13{
14currentControl=ctrl;
15AddEvents();
16}
17#endregion
18
19#regionFields
20privateControlcurrentControl;//传入的控件
21privatePointpPoint;//上个鼠标坐标
22privatePointcPoint;//当前鼠标坐标
23#endregion
24
25#regionProperties
26
27#endregion
28
29#regionMethods
30///
31///挂载事件
32///
33privatevoidAddEvents()
34{
35currentControl.MouseDown+=newMouseEventHandler(MouseDown);
36currentControl.MouseMove+=newMouseEventHandler(MouseMove);
37currentControl.MouseUp+=newMouseEventHandler(MouseUp);
38}
39
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///鼠标按下事件:
记录当前鼠标相对窗体的坐标
58///
59voidMouseDown(objectsender,MouseEventArgse)
60{
61pPoint=Cursor.Position;
62}
63
64///
65///鼠标移动事件:
让控件跟着鼠标移动
66///
67voidMouseMove(objectsender,MouseEventArgse)
68{
69Cursor.Current=Cursors.SizeAll;//当鼠标处于控件内部时,显示光标样式为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}
7}
此时,有心人可能会发现VS中拖动控件时,将会出现黑色边框,而处于没有。
这也很简单,我们在MouseMove时加上如下代码即可。
1///
2///绘制拖拉时的黑色边框
3///
4publicstaticvoidDrawDragBound(Controlctrl)
5{
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;//当鼠标处于控件内部时,显示光标样式为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的时候,刷新一下自己,让黑色边框消失掉!
1///
2///鼠标弹起事件:
让自定义的边框出现
3///
4voidMouseUp(objectsender,MouseEventArgse)
5{
6this.currentControl.Refresh();
7}
接着用没有边框的控件测试下就会很明显。
如下图所示:
2.通过边框拖拉控件改变大小
此处的主要思路为:
点击控件的时候,创建一个自定义的用户控件,该用户控件响应区域就是传入控件的边框区域,同时给它画上虚线与8个小圆圈。
第一、创建用户控件--FrameControl(边框控件),然后增加一个字段用来保存传入的控件,还有加载事件,此处类同前面的MoveControl。
FrameControl
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.ComponentModel;
4usingSystem.Drawing;
5usingSystem.Data;
6usingSystem.Linq;
7usingSystem.Text;
8usingSystem.Windows.Forms;
9
10namespaceDragControl
11{
12publicpartialclassFrameControl:
UserControl
13{
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
38#endregion
39
40#regionEvents
41///
42///鼠标按下事件:
记录当前鼠标相对窗体的坐标
43///
44voidFrameControl_MouseDown(objectsender,MouseEventArgse)
45{
46
47}
48
49///
50///鼠标移动事件:
让控件跟着鼠标移动
51///
52voidFrameControl_MouseMove(objectsender,MouseEventArgse)
53{
54
55}
56
57///
58///鼠标弹起事件:
让自定义的边框出现
59///
60voidFrameControl_MouseUp(objectsender,MouseEventArgse)
61{
62
63}
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()
24{
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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 实现拖拉控件改变位置与大小SamWang 实现 拖拉 控件 改变 位置 大小 SamWang