你愿意做我女朋友吗表白网站北京4网站建设
你愿意做我女朋友吗表白网站,北京4网站建设,如何建设影视网站,怎么更新网站内容前言#xff1a;很多时候我们需要在运行时#xff0c;动态地改变控件的位置以及大小#xff0c;以获得更好的布局。比如说实际项目中的可自定义的报表、可自定义的单据等诸如此类。它们有个特点就是允许客户或者二次开发人员设计它们需要的界面设置功能。本人以前也做过可自…前言很多时候我们需要在运行时动态地改变控件的位置以及大小以获得更好的布局。比如说实际项目中的可自定义的报表、可自定义的单据等诸如此类。它们有个特点就是允许客户或者二次开发人员设计它们需要的界面设置功能。本人以前也做过可自定义系统包括界面和功能主要为了减少开发人员的工作量以及程序的灵活性和健壮性。本篇主要讨论下在运行时如何实现拖拉控件达到改变控件位置与大小。功能将模拟VS设计界面时的拖拉功能。(本篇暂不涉及多控件同时操作)一、技术概述其实实现运行时控件的拖拉并不难主要是改变控件的Location与Size即可。动态调整时再捕获MouseDown、MouseMove及MouseUp事件来实时修改上述两个属性就可以实现。二、功能规划在此之前我们先来看下.net设计界面一旦选中某个控件时将会出现如下图的边框之后就可以通过拖拉出现的边框改变其大小。而改变控件的位置实际上是当鼠标点击在控件内部拖动时实现的。所有本例也将功能分为两个部分实现分别为控件内部拖动改变位置与控件边框拖拉改变大小。三、具体实现1.拖动控件改变位置首先新建一个项目然后添加一个类取名叫MoveControl该类用来给控件挂载事件实现拖动。接着在该类中添加字段currentControl用来保存需要操作的控件即通过构造函数传递的控件。接着创建一方法--AddEvents,用来给当前的控件挂载事件。代码如下DragControl1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Windows.Forms;5 usingSystem.Drawing;67 namespaceDragControl8 {9 public classMoveControl10 {11 #region Constructors12 publicMoveControl(Control ctrl)13 {14 currentControl ctrl;15 AddEvents();16 }17 #endregion1819 #region Fields20 private Control currentControl; //传入的控件21 #endregion2223 #region Properties2425 #endregion2627 #region Methods28 /// 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 #endregion3940 #region Events41 /// 42 ///鼠标单击事件用来显示边框43 /// 44 /// 45 /// 46 void MouseClick(objectsender, MouseEventArgs e)47 {48 }4950 /// 51 ///鼠标按下事件记录当前鼠标相对窗体的坐标52 /// 53 void MouseDown(objectsender, MouseEventArgs e)54 {5556 }5758 /// 59 ///鼠标移动事件让控件跟着鼠标移动60 /// 61 void MouseMove(objectsender, MouseEventArgs e)62 {63 }6465 /// 66 ///鼠标弹起事件让自定义的边框出现67 /// 68 void MouseUp(objectsender, MouseEventArgs e)69 {70 }71 #endregion72 }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的完整代码如下MoveControl1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Windows.Forms;5 usingSystem.Drawing;67 namespaceDragControl8 {9 public classMoveControl10 {11 #region Constructors12 publicMoveControl(Control ctrl)13 {14 currentControl ctrl;15 AddEvents();16 }17 #endregion1819 #region Fields20 private Control currentControl; //传入的控件21 private Point pPoint; //上个鼠标坐标22 private Point cPoint; //当前鼠标坐标23 #endregion2425 #region Properties2627 #endregion2829 #region Methods30 /// 31 ///挂载事件32 /// 33 private voidAddEvents()34 {35 currentControl.MouseDown newMouseEventHandler(MouseDown);36 currentControl.MouseMove newMouseEventHandler(MouseMove);37 currentControl.MouseUp newMouseEventHandler(MouseUp);38 }3940 /// 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 #endregion5455 #region Events56 /// 57 ///鼠标按下事件记录当前鼠标相对窗体的坐标58 /// 59 void MouseDown(objectsender, MouseEventArgs e)60 {61 pPoint Cursor.Position;62 }6364 /// 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 }8182 /// 83 ///鼠标弹起事件让自定义的边框出现84 /// 85 void MouseUp(objectsender, MouseEventArgs e)86 {87 this.currentControl.Refresh();88 }89 #endregion90 }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 }141516 /// 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 }接着用没有边框的控件测试下就会很明显。如下图所示2.通过边框拖拉控件改变大小此处的主要思路为点击控件的时候创建一个自定义的用户控件该用户控件响应区域就是传入控件的边框区域同时给它画上虚线与8个小圆圈。第一、创建用户控件--FrameControl(边框控件)然后增加一个字段用来保存传入的控件还有加载事件此处类同前面的MoveControl。FrameControl1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.ComponentModel;4 usingSystem.Drawing;5 usingSystem.Data;6 usingSystem.Linq;7 usingSystem.Text;8 usingSystem.Windows.Forms;910 namespaceDragControl11 {12 public partial classFrameControl : UserControl13 {14 #region Constructors15 publicFrameControl(Control ctrl)16 {17 baseControl ctrl;18 AddEvents();19 }20 #endregion2122 #region Fields23 Control baseControl; //基础控件即被包围的控件24 #endregion2526 #region Methods27 /// 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 }3738 #endregion3940 #region Events41 /// 42 ///鼠标按下事件记录当前鼠标相对窗体的坐标43 /// 44 void FrameControl_MouseDown(objectsender, MouseEventArgs e)45 {4647 }4849 /// 50 ///鼠标移动事件让控件跟着鼠标移动51 /// 52 void FrameControl_MouseMove(objectsender, MouseEventArgs e)53 {5455 }5657 /// 58 ///鼠标弹起事件让自定义的边框出现59 /// 60 void FrameControl_MouseUp(objectsender, MouseEventArgs e)61 {6263 }64 #endregion65 }66 }做完这些准备工作后将到了主要的部分就是给控件画边框。整个边框分为三个部分四边框(用来设置可视区域与区域)四条虚线(只用来显示)八个小圆圈(用来斜角拖拉)。所以要建立三个字段用来分别保存这个数据。Rectangle[] smallRects new Rectangle[8];//边框中的八个小圆圈Rectangle[] sideRects new Rectangle[4];//四条边框用来做响应区域Point[] linePoints new Point[5];//四条边用于画虚线接着就是创建用户控件的可视区域和上面的三个变量数值。(以下计算位置的代码有兴趣的人可以研究下没有的就直接Copy)创建边框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 }1920 /// 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);4142 //四条边线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);5354 //整个包括周围边框的范围55 ControlRect new Rectangle(new Point(0, 0), this.Bounds.Size);56 }5758 /// 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);7374 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的时候再显示。此时的完整代码如下MoveControl1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Text;4 usingSystem.Windows.Forms;5 usingSystem.Drawing;67 namespaceDragControl8 {9 public classMoveControl10 {11 #region Constructors12 publicMoveControl(Control ctrl)13 {14 currentControl ctrl;15 AddEvents();16 }17 #endregion1819 #region Fields20 private Control currentControl; //传入的控件21 private Point pPoint; //上个鼠标坐标22 private Point cPoint; //当前鼠标坐标23 FrameControl fc;//边框控件24 #endregion2526 #region Properties2728 #endregion2930 #region Methods31 /// 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 }4142 /// 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 #endregion5657 #region Events58 /// 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 }7273 /// 74 ///鼠标按下事件记录当前鼠标相对窗体的坐标75 /// 76 void MouseDown(objectsender, MouseEventArgs e)77 {78 pPoint Cursor.Position;79 }8081 /// 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 }99100 /// 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 #endregion113 }114 }FrameControl1 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;910 namespaceDragControl11 {12 public partial classFrameControl : UserControl13 {14 #region Constructors15 publicFrameControl(Control ctrl)16 {17 baseControl ctrl;18 AddEvents();19 CreateBounds();20 }21 #endregion2223 #region Fields24 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 #endregion3334 #region Methods35 /// 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 }4546 #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 }6465 /// 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);8687 //四条边线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);9899 //整个包括周围边框的范围100 ControlRect new Rectangle(new Point(0, 0), this.Bounds.Size);101 }102103 /// 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);118119 path.AddRectangle(sideRects[0]);120 path.AddRectangle(sideRects[1]);121 path.AddRectangle(sideRects[2]);122 path.AddRectangle(sideRects[3]);123 returnpath;124 }125 #endregion126127 /// 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 }143144 #endregion145146 #region Events147 /// 148 ///鼠标按下事件记录当前鼠标相对窗体的坐标149 /// 150 void FrameControl_MouseDown(objectsender, MouseEventArgs e)151 {152153 }154155 /// 156 ///鼠标移动事件让控件跟着鼠标移动157 /// 158 void FrameControl_MouseMove(objectsender, MouseEventArgs e)159 {160161 }162163 /// 164 ///鼠标弹起事件让自定义的边框出现165 /// 166 void FrameControl_MouseUp(objectsender, MouseEventArgs e)167 {168169 }170 #endregion171 }172 }测试界面到目前为止还只是有边框下面将实现拖拉功能。首先来实现当鼠标放在响应区域的时候根据不同的位置显示不同的箭头样子。为此先创建一个枚举用来记录当前鼠标的位置等拖拉的时候根据该枚举值做不同的计算。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 else53 {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 }89 /// 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 else21 {22 this.Visible true;23 SetCursorShape(e.X, e.Y); //更新鼠标指针样式24 }25 }2627 /// 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 else18 {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 else29 {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 else40 {41 baseControl.Left - MinWidth -baseControl.Width;42 baseControl.Width MinWidth;43 }4445 break;46 caseMousePosOnCtrl.RIGHT:47 if (baseControl.Width x MinWidth)48 {49 baseControl.Width x;50 }51 else52 {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 else63 {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 else73 {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 else85 {86 baseControl.Top - MinHeight -baseControl.Height;87 baseControl.Height MinHeight;88 }89 if (baseControl.Width x MinWidth)90 {91 baseControl.Width x;92 }93 else94 {95 baseControl.Width MinWidth;96 }97 break;98 caseMousePosOnCtrl.BOTTOMLEFT:99 if (baseControl.Height y MinHeight)100 {101 baseControl.Height y;102 }103 else104 {105 baseControl.Height MinHeight;106 }107 if (baseControl.Width - x MinWidth)108 {109 baseControl.Left x;110 baseControl.Width -x;111 }112 else113 {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 else124 {125 baseControl.Height MinHeight;126 }127 if (baseControl.Width x MinWidth)128 {129 baseControl.Width x;130 }131 else132 {133 baseControl.Width MinWidth;134 }135 break;136137 }138 pPoint Cursor.Position;139 }到此为止功能已经基本上实现。完成代码如下MoveControl1 /******************************************************************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;1617 namespaceDragControl18 {19 public classMoveControl20 {21 #region Constructors22 publicMoveControl(Control ctrl)23 {24 currentControl ctrl;25 AddEvents();26 }27 #endregion2829 #region Fields30 private Control currentControl; //传入的控件31 private Point pPoint; //上个鼠标坐标32 private Point cPoint; //当前鼠标坐标33 FrameControl fc;//边框控件34 #endregion3536 #region Properties3738 #endregion3940 #region Methods41 /// 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 }5152 /// 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 }6566 #endregion6768 #region Events69 /// 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 }8384 /// 85 ///鼠标按下事件记录当前鼠标相对窗体的坐标86 /// 87 void MouseDown(objectsender, MouseEventArgs e)88 {89 pPoint Cursor.Position;90 }9192 /// 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 }110111 /// 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 #endregion124 }125 }FrameControl1 /******************************************************************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;1617 namespaceDragControl18 {19 public classFrameControl : UserControl20 {21 #region Constructors22 /// 23 ///构造函数24 /// 25 publicFrameControl(Control ctrl)26 {27 baseControl ctrl;28 AddEvents();29 CreateBounds();30 }31 #endregion3233 #region Fields34 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 #endregion4849 #region Properties50 /// 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 #endregion6667 #region Methods68 /// 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 }7879 #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 }9798 /// 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);119120 //四条边线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);131132 //整个包括周围边框的范围133 ControlRect new Rectangle(new Point(0, 0), this.Bounds.Size);134 }135136 /// 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);151152 path.AddRectangle(sideRects[0]);153 path.AddRectangle(sideRects[1]);154 path.AddRectangle(sideRects[2]);155 path.AddRectangle(sideRects[3]);156 returnpath;157 }158 #endregion159160 /// 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 }177178 /// 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 else230 {231 Cursor.Current Cursors.Arrow;232 }233 return true;234 }235236 /// 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 else253 {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 else264 {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 else275 {276 baseControl.Left - MinWidth -baseControl.Width;277 baseControl.Width MinWidth;278 }279280 break;281 caseMousePosOnCtrl.RIGHT:282 if (baseControl.Width x MinWidth)283 {284 baseControl.Width x;285 }286 else287 {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 else298 {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 else308 {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 else320 {321 baseControl.Top - MinHeight -baseControl.Height;322 baseControl.Height MinHeight;323 }324 if (baseControl.Width x MinWidth)325 {326 baseControl.Width x;327 }328 else329 {330 baseControl.Width MinWidth;331 }332 break;333 caseMousePosOnCtrl.BOTTOMLEFT:334 if (baseControl.Height y MinHeight)335 {336 baseControl.Height y;337 }338 else339 {340 baseControl.Height MinHeight;341 }342 if (baseControl.Width - x MinWidth)343 {344 baseControl.Left x;345 baseControl.Width -x;346 }347 else348 {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 else359 {360 baseControl.Height MinHeight;361 }362 if (baseControl.Width x MinWidth)363 {364 baseControl.Width x;365 }366 else367 {368 baseControl.Width MinWidth;369 }370 break;371372 }373 pPoint Cursor.Position;374 }375376 #endregion377378 #region Events379 /// 380 ///鼠标按下事件记录当前鼠标相对窗体的坐标381 /// 382 void FrameControl_MouseDown(objectsender, MouseEventArgs e)383 {384 pPoint Cursor.Position;385 }386387 /// 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 else399 {400 this.Visible true;401 SetCursorShape(e.X, e.Y); //更新鼠标指针样式402 }403 }404405 /// 406 ///鼠标弹起事件让自定义的边框出现407 /// 408 void FrameControl_MouseUp(objectsender, MouseEventArgs e)409 {410 this.baseControl.Refresh(); //刷掉黑色边框411 this.Visible true;412 CreateBounds();413 Draw();414 }415 #endregion416 }417 }四、遗留问题1.ListBox存在拖拉高度时存在莫名奇妙的BUG。2.目前该版本只支持单控件的拖拉多控件同时拖拉等下次有空再弄。五、附源代码下载SamWang2012-05-14作者SamWang出处http://wangshenhe.cnblogs.com/本文版权归作者和博客园共有欢迎围观转载。转载时请您务必在文章明显位置给出原文链接谢谢您的合作。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/90182.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!