directory
A, preview
Second, the cause of
Three, the perfect
Four,
1. Control style of form design
2. Bind events to the control
Five, make the border control FrameControl
1. Set the control area
2. Draw a dotted line
3. Draw a solid line
4. Change the mouse status
5. Adjust the control size
6. Bind events to border controls
The extension method ControlExtensions
Seven, the use of
NuGet searches winForm.movecontrol
Nine, the source code
A, preview
Let’s see what happens
The effect is ok…
Second, the cause of
Recently, a couple of guys wrote me a question about WinForm, about dragging and dropping controls, like resizing and positioning controls at form design time.
In fact, I wrote a related article before, in 2019, haha, it has been two years. I also sent the source code before, but it may not be very clear, the code also has bugs and is not perfect.
The WinForm runtime mimics the form design and adjusts the size and position of controls
So I refined the code and uploaded it to GitHub so it could be updated.
I was forced to upload GitHub, which was uploaded to CSDN resources before. The system dynamically adjusted the points, but now the points need 50 to download. I was scolded, saying that it was so expensive. True injustice, clearly is the system dynamic adjustment. Now look at the uploaded resources, the newly uploaded resources can be manually set points, not subject to system adjustment, but also not uploaded, directly on GitHub…
This is the previously uploaded resource WinForm runtime that mimics the form design to resize and position controls
Several improvements have been made to the previous code, and some of the issues left over from last time have been addressed
Three, the perfect
Compared with last project, perfect place
- Fixed the problem of the mouse cursor returning to the default state when resizing the control
- Perfect the border control, can set the border transparent, border cover other controls
- Specification code, modularization, add detailed comments, upload GitHub
This time free, do not need to score, directly on GitHub, the following to the resource address
Four,
Although I wrote an article before and now REWRITE it, many functions are similar, some are improved, some are the same
1. Control style of form design
First, let’s look at the control style at form design time
Click on the control to display 4 dashed lines and 8 small rectangles, but at the same time we need to set 4 more bottom edges to draw the dashed lines and rectangles
Four solid lines are displayed when the control is moved
2. Bind events to the control
To adjust the size and position of the control at run time, simply bind the MouseDown, MouseClick, MouseMove, MouseUp events to the control. MouseUp: When the mouse is released, 4 dashed lines and 8 small rectangles are displayed. MouseMove: When the mouse is dragged, a solid gray line is displayed. This event is also executed when the mouse is clicked
We can use GDI+ drawing technology to draw solid and dashed gray lines of the control
MouseDown: When the mouse button is pressed, it records the position of the mouse. MouseMove: When you move the mouse over the control, refresh the 4 solid gray lines while resizing the control. Change the mouse cursor and adjust the control’s size MouseUp: Refresh the 4 dashed lines when the mouse key is released
Optionally, you can bind the MouseLeave event to hide the border when the mouse leaves the control
The border control contains four bottom edges of the border, four solid gray lines, four dashed lines, and eight small rectangles
Five, make the border control FrameControl
Border controls first need to inherit UserControl
Bind the MouseDown, MouseMove, MouseUp events
Next, write a few important methods
- Set the control area: 4 bottom edges, click the control after display
- Draw dashed lines: 4 dashed lines and 8 small rectangles, which are called in OnPaint
- Draw solid line: 4 solid lines, move the control and resize the control display
- Change the mouse state, mouse control on, down, left, right, left up, right up, left down, right down, up different cursor
- Resize the control: Adjust the size of the control when the mouse is in different positions in the control
This method needs to be called in OnPaint because border controls do not overwrite other controls in order to be transparent
You need to set control transparency support in the border control FrameControl
</ / </summary> protected Override CreateParams CreateParams {get {CreateParams cp = base.CreateParams; cp.ExStyle |= 0x20; return cp; }}Copy the code
1. Set the control area
Set the border control display and top, set 4 bottom edges for the control area
// </summary> public void SetControlRegion() {// Display Visible = true; BringToFront(); Int x = control.bounds. x - smallRectSize.Width; int y = control.Bounds.Y - smallRectSize.Height; int width = control.Bounds.Width + (smallRectSize.Width * 2); int height = control.Bounds.Height + (smallRectSize.Height * 2); Bounds = new Rectangle(x, y, width, height); ControlRect = new Rectangle(new Point(0, 0), bound.size); #endregion #region GraphicsPath path = new GraphicsPath(); BorderRects [0] = new Rectangle(0, 0, Width + size * 2, smallRectSize.Height + 1); BorderRects [1] = new Rectangle(0, size + 1, SmallRectsize. Width + 1, height-size * 2-2); BorderRects [2] = new Rectangle(0, height-size-1, Width + size * 2, smallRectSize.Height + 1); BorderRects [3] = new Rectangle(Width - size - 1, size + 1, smallRectSize.Width + 1, height-size * 2-2); path.AddRectangle(borderRects[0]); path.AddRectangle(borderRects[1]); path.AddRectangle(borderRects[2]); path.AddRectangle(borderRects[3]); Region = new Region(path); #endregion }Copy the code
2. Draw a dotted line
Draw 4 dotted lines and 8 small rectangles
/// <summary> Public void DrawDottedLines(Graphics g) {# Point [0] = new Point(3, 3); // right linePoints[1] = new Point(Width -3-1, 3); // right linePoints[2] = new Point(Width -3-1, height-3-1); // linePoints[3] = new Point(3, height-3-1); // linepoint [4] = new Point(3, 3); Pen pen = new Pen(Color.Black, 1) { DashStyle = DashStyle.Dot }; g.DrawLines(pen, linePoints); SmallRects [0] = new Rectangle(New Point(0, 0), smallRectSize); SmallRects [1] = new Rectangle(new Point(width-size-1, 0), smallRectSize); SmallRects [2] = new Rectangle(new Point(0, height-size-1), smallRectSize); SmallRects [3] = new Rectangle(new Point(width-size-1, height-size-1), smallRectSize); // Rectangle [4] = New Rectangle(new Point(Width / 2-1, 0), Rectangle(Width / 2-1, 0)); // Rectangle [5] = new Rectangle(new Point(Width / 2-1, height-size-1), smallRectSize); // Rectangle [5] = new Rectangle(Width / 2-1, height-size-1), smallRectSize); // Rectangle [6] = new Rectangle(new Point(0, Height / 2-size / 2), Rectangle(Height / 2-size / 2)); // Rectangle [7] = new Rectangle(new Point(Width - size - 1, Height / 2 - size / 2), Rectangle(Height / 2 - size / 2)); // Fill the rectangles with White g. rectangles (Brushes. // Rectangles g. rectangles (Pens.Black, smallRects); #endregion }Copy the code
3. Draw a solid line
Draw 4 solid lines, move the control and resize the control display
/// </summary> public void DrawSolids() {// Hide bezel Visible = false; Graphics g = control.CreateGraphics(); int width = control.Width; int height = control.Height; Point[] points = new Point[5] {new Point(0,0),new Point(width-1,0), New Point(width -1,height-1),new Point(0,height-1),new Point(0,0)}; g.DrawLines(new Pen(Color.Gray, 3), points); }Copy the code
4. Change the mouse status
Start by defining an enumeration that stores the position of the mouse in the control
// </summary> enum MousePos {None, Top, Right, Bottom, Left, LeftTop, LeftBottom, // </summary> // </summary> MousePos MousePos; /// change the mouse state, mouse on the control, down, left, right, left up, right up, left down, right down, Private void SetCursor(int x, int y) {Point Point = new Point(x, y); if (! Controlrect. Contains(point)) {Cursors. Current = Cursors.Arrow; return; } else if (smallRects[0].Contains(point))// Left upper {Cursors. mousePos = MousePos.LeftTop; } else if (smallRects[1].Contains(point))// Right upper {Cursors. mousePos = MousePos.RightTop; } else if (smallRects[2].Contains(point)) {Cursors. mousePos = MousePos.LeftBottom; } else if (Cursors [3].Contains(point)) {Cursors. Current = SizeNWSE; mousePos = MousePos.RightBottom; } else if (borderRects[0].Contains(point))// on {Cursors. mousePos = MousePos.Top; } else if (borderRects[1].Contains(point))// left {Cursors. Current = Cursors. mousePos = MousePos.Left; } else if (borderRects[2].Contains(point))// down {Cursors. mousePos = MousePos.Bottom; } else if (borderRects[3].Contains(point))// right {Cursors. Current = Cursors. mousePos = MousePos.Right; } else { Cursor.Current = Cursors.Arrow; }}Copy the code
5. Adjust the control size
Adjust the size of the control with the mouse at different positions in the control
// <summary> // // </summary> private void ReCtrlSize() {// Get current Cursor Position Point currentPoint = cursor.position; int x = currentPoint.X - lastPoint.X; int y = currentPoint.Y - lastPoint.Y; switch (mousePos) { case MousePos.None: break; Case MousePos.Top:// adjust if (control.Height -y > MinHeight) {control. control.Height -= y; } break; case MousePos.Right: if (control.Width + x > MinWeight) { control.Width += x; } break; case MousePos.Bottom: if (control.Height + y > MinHeight) { control.Height += y; } break; case MousePos.Left: if (control.Width - x > MinWeight) { control.Left += x; control.Width -= x; } break; Case mousepos. LeftTop:// If (control.Width -x > MinWeight) {control.Left += x; control.Width -= x; } if (control.Height - y > MinHeight) { control.Top += y; control.Height -= y; } break; case MousePos.LeftBottom: if (control.Width - x > MinWeight) { control.Left += x; control.Width -= x; } if (control.Height + y > MinHeight) { control.Height += y; } break; case MousePos.RightTop: if (control.Width + x > MinWeight) { control.Width += x; } if (control.Height - y > MinHeight) { control.Top += y; control.Height -= y; } break; case MousePos.RightBottom: if (control.Width + x > MinWeight) { control.Width += x; } if (control.Height + y > MinHeight) { control.Height += y; } break; default: break; } lastPoint = Cursor.Position; }Copy the code
For example, adjust the Height property of the control when the mouse is below it
6. Bind events to border controls
Adding SetCursor to the MouseDown event solves the problem that the mouse cursor will become the default state when the control is resized. Now the mouse cursor will become the arrow state when the control is resized
MouseDown += (sender, e) => {// Record Cursor Position lastPoint = cursor.position; // Change cursor state SetCursor(e.X, e.Y); }; / / mouse movement, namely the adjustment control size MouseMove + = (sender, e) = > {/ / the Left mouse button if (e.B utton = = MouseButtons. Left) {/ / mobile solid DrawSolids refresh (); // Resize the control ReCtrlSize(); SetCursor(e.X, e.Y);} // Cursor cursor (e.X, e.Y); }}; // MouseUp += (sender, e) => {control.refresh (); // display dashed line SetControlRegion(); }; //// mouse off control hide border //MouseLeave += (sender, e) => //{// this.visible = false; / /};Copy the code
That completes the border control part, and it’s time to add border controls to the controls you want, but if you have too much code to bind each control, you can use the extension method instead
The extension method ControlExtensions
Bind MouseDown, MouseClick, MouseMove, MouseUp events to the desired control
Public static class ControlExtensions {/// <summary> // </summary> public static void SetMove(this) Control Control) {// FrameControl FrameControl fControl = null; // lastPoint = new Point(); Control.mousedown += (sender, e) => {// Record Cursor Position lastPoint = cursor.position; // Clear the border area of all controls, most importantly, clear the border of the control that was clicked last time, Foreach (Control CTRL in Control.parent.Controls) if (CTRL is FrameControl) Ctrl. Visible = false; if (fControl == null) fControl = new FrameControl(control); BackColor = color.transparent; fcontrol.backcolor = color.transparent; / / Add a border Controls to control. In the current control the Parent control. The Parent Controls. The Add (fControl); }; Control.mouseclick += (sender, e) => {control.bringTofront (); }; Control.mousemove += (sender, e) => {Point currentPoint = new Point(); Cursor.Current = Cursors.SizeAll; if (e.Button == MouseButtons.Left) { currentPoint = Cursor.Position; control.Location = new Point(control.Location.X + currentPoint.X - lastPoint.X, control.Location.Y + currentPoint.Y - lastPoint.Y); // Refresh solid fcontrol.drawsolids (); control.BringToFront(); } lastPoint = currentPoint; }; / / mouse button is released the control. The MouseUp + = (sender, e) = > {/ / Settings control area fControl. SetControlRegion (); }; #endregion } }Copy the code
Seven, the use of
It’s easy to use, set in the Form’s Load event, with just one line of code
button1.SetMove();
Copy the code
The effect
Complete… Perfect…
NuGet searches winForm.movecontrol
I made the project into a Nuget package and uploaded it to Nuget. Search for winForm. MoveControl installation in Nuget
Or using commands
Install - Package WinForm. MoveControl - Version 1.0.5Copy the code
See another article on how to make NuGet packages:
Greambwang.blog.csdn.net/article/det…
Finally go to GitHub, get the source code, remember to give a Star
Nine, the source code
GitHub:github.com/GreAmbWang/…
Nuget:www.nuget.org/packages/Wi…