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

  1. Fixed the problem of the mouse cursor returning to the default state when resizing the control
  2. Perfect the border control, can set the border transparent, border cover other controls
  3. 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…