How Can User Resize Control at Runtime in Winforms

Is it possible to create by user in runtime controls (button,image) that has a resizer frame designtime?

You could create new controls based on the original control you want to be able to resize (inheritence) and make them resizable.

Look at this:

How can user resize control at runtime in winforms

Code: (from link above)

class SizeablePictureBox : PictureBox {
public SizeablePictureBox() {
this.ResizeRedraw = true;
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
var rc = new Rectangle(this.ClientSize.Width - grab, this.ClientSize.Height - grab, grab, grab);
ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == 0x84) { // Trap WM_NCHITTEST
var pos = this.PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16));
if (pos.X >= this.ClientSize.Width - grab && pos.Y >= this.ClientSize.Height - grab)
m.Result = new IntPtr(17); // HT_BOTTOMRIGHT
}
}
private const int grab = 16;
}

Resize Controls with Form Resize

I found an alternative solution that is working well for me, appreciate any negative or positive comments on the solution.

Using several Split Containers and Split Containers inside of Split Containers in different regions I am able to section off the primary pieces of the layout, and within there utilizing Docking and Anchoring I am able to accomplish exactly what I wanted to do - it works beautifully.

I would point out I am aware that some folks online mention split containers use lots of resources.

Resizing control at runtime

Pretty much the only way to cleanly allow .NET control resizing is to use P/Invoke. This exact code is not tested, but I have used this resizing method many times so it should work:

First, the P/Invoke external declarations:

private static class UnsafeNativeMethods
{
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}

Next, call the P/Invoke functions to have the operating system handle the resize:

protected override void OnMouseDown(MouseEventArgs e)
{
int msg = -1; //if (msg == -1) at the end of this, then the mousedown is not a drag.

if (e.Y < 8)
{
msg = 12; //Top
if (e.X < 25) msg = 13; //Top Left
if (e.X > Width - 25) msg = 14; //Top Right
}
else if (e.X < 8)
{
msg = 10; //Left
if (e.Y < 17) msg = 13;
if (e.Y > Height - 17) msg = 16;
}
else if (e.Y > Height - 9)
{
msg = 15; //Bottom
if (e.X < 25) msg = 16;
if (e.X > Width - 25) msg = 17;
}
else if (e.X > Width - 9)
{
msg = 11; //Right
if (e.Y < 17) msg = 14;
if (e.Y > Height - 17) msg = 17;
}

if (msg != -1)
{
UnsafeNativeMethods.ReleaseCapture(); //Release current mouse capture
UnsafeNativeMethods.SendMessage(Handle, 0xA1, new IntPtr(msg), IntPtr.Zero);
//Tell the OS that you want to drag the window.
}
}

Finally, override OnMouseMove to change the cursor based on where it is on the control. I'll leave that part to you, because it's almost the same code as the previous snippet.

Resize User Control in Form

Try setting a Control.MaximumSizefor the control. You can use the Control.Anchor property to align it in the parent form/control.

Is it possible to resize a control dynamically?

See if this component fulfils your requirements.

Note I didn't create the component, found it on the web a while back.

Usage

ControlMoverOrResizer.Init(panel1);

Component

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;

namespace ControlManager
{
internal class ControlMoverOrResizer
{
private static bool _moving;
private static Point _cursorStartPoint;
private static bool _moveIsInterNal;
private static bool _resizing;
private static Size _currentControlStartSize;
internal static bool MouseIsInLeftEdge { get; set; }
internal static bool MouseIsInRightEdge { get; set; }
internal static bool MouseIsInTopEdge { get; set; }
internal static bool MouseIsInBottomEdge { get; set; }

internal enum MoveOrResize
{
Move,
Resize,
MoveAndResize
}

internal static MoveOrResize WorkType { get; set; }

internal static void Init(Control control)
{
Init(control, control);
}

internal static void Init(Control control, Control container)
{
_moving = false;
_resizing = false;
_moveIsInterNal = false;
_cursorStartPoint = Point.Empty;
MouseIsInLeftEdge = false;
MouseIsInLeftEdge = false;
MouseIsInRightEdge = false;
MouseIsInTopEdge = false;
MouseIsInBottomEdge = false;
WorkType = MoveOrResize.MoveAndResize;
control.MouseDown += (sender, e) => StartMovingOrResizing(control, e);
control.MouseUp += (sender, e) => StopDragOrResizing(control);
control.MouseMove += (sender, e) => MoveControl(container, e);
}

private static void UpdateMouseEdgeProperties(Control control, Point mouseLocationInControl)
{
if (WorkType == MoveOrResize.Move)
{
return;
}
MouseIsInLeftEdge = Math.Abs(mouseLocationInControl.X) <= 2;
MouseIsInRightEdge = Math.Abs(mouseLocationInControl.X - control.Width) <= 2;
MouseIsInTopEdge = Math.Abs(mouseLocationInControl.Y ) <= 2;
MouseIsInBottomEdge = Math.Abs(mouseLocationInControl.Y - control.Height) <= 2;
}

private static void UpdateMouseCursor(Control control)
{
if (WorkType == MoveOrResize.Move)
{
return;
}
if (MouseIsInLeftEdge )
{
if (MouseIsInTopEdge)
{
control.Cursor = Cursors.SizeNWSE;
}
else if (MouseIsInBottomEdge)
{
control.Cursor = Cursors.SizeNESW;
}
else
{
control.Cursor = Cursors.SizeWE;
}
}
else if (MouseIsInRightEdge)
{
if (MouseIsInTopEdge)
{
control.Cursor = Cursors.SizeNESW;
}
else if (MouseIsInBottomEdge)
{
control.Cursor = Cursors.SizeNWSE;
}
else
{
control.Cursor = Cursors.SizeWE;
}
}
else if (MouseIsInTopEdge || MouseIsInBottomEdge)
{
control.Cursor = Cursors.SizeNS;
}
else
{
control.Cursor = Cursors.Default;
}
}

private static void StartMovingOrResizing(Control control, MouseEventArgs e)
{
if (_moving || _resizing)
{
return;
}
if (WorkType!=MoveOrResize.Move &&
(MouseIsInRightEdge || MouseIsInLeftEdge || MouseIsInTopEdge || MouseIsInBottomEdge))
{
_resizing = true;
_currentControlStartSize = control.Size;
}
else if (WorkType!=MoveOrResize.Resize)
{
_moving = true;
control.Cursor = Cursors.Hand;
}
_cursorStartPoint = new Point(e.X, e.Y);
control.Capture = true;
}

private static void MoveControl(Control control, MouseEventArgs e)
{
if (!_resizing && ! _moving)
{
UpdateMouseEdgeProperties(control, new Point(e.X, e.Y));
UpdateMouseCursor(control);
}
if (_resizing)
{
if (MouseIsInLeftEdge)
{
if (MouseIsInTopEdge)
{
control.Width -= (e.X - _cursorStartPoint.X);
control.Left += (e.X - _cursorStartPoint.X);
control.Height -= (e.Y - _cursorStartPoint.Y);
control.Top += (e.Y - _cursorStartPoint.Y);
}
else if (MouseIsInBottomEdge)
{
control.Width -= (e.X - _cursorStartPoint.X);
control.Left += (e.X - _cursorStartPoint.X);
control.Height = (e.Y - _cursorStartPoint.Y) + _currentControlStartSize.Height;
}
else
{
control.Width -= (e.X - _cursorStartPoint.X);
control.Left += (e.X - _cursorStartPoint.X) ;
}
}
else if (MouseIsInRightEdge)
{
if (MouseIsInTopEdge)
{
control.Width = (e.X - _cursorStartPoint.X) + _currentControlStartSize.Width;
control.Height -= (e.Y - _cursorStartPoint.Y);
control.Top += (e.Y - _cursorStartPoint.Y);

}
else if (MouseIsInBottomEdge)
{
control.Width = (e.X - _cursorStartPoint.X) + _currentControlStartSize.Width;
control.Height = (e.Y - _cursorStartPoint.Y) + _currentControlStartSize.Height;
}
else
{
control.Width = (e.X - _cursorStartPoint.X)+_currentControlStartSize.Width;
}
}
else if (MouseIsInTopEdge)
{
control.Height -= (e.Y - _cursorStartPoint.Y);
control.Top += (e.Y - _cursorStartPoint.Y);
}
else if (MouseIsInBottomEdge)
{
control.Height = (e.Y - _cursorStartPoint.Y) + _currentControlStartSize.Height;
}
else
{
StopDragOrResizing(control);
}
}
else if (_moving)
{
_moveIsInterNal = !_moveIsInterNal;
if (!_moveIsInterNal)
{
int x = (e.X - _cursorStartPoint.X) + control.Left;
int y = (e.Y - _cursorStartPoint.Y) + control.Top;
control.Location = new Point(x, y);
}
}
}

private static void StopDragOrResizing(Control control)
{
_resizing = false;
_moving = false;
control.Capture = false;
UpdateMouseCursor(control);
}

#region Save And Load

private static List<Control> GetAllChildControls(Control control, List<Control> list)
{
List<Control> controls = control.Controls.Cast<Control>().ToList();
list.AddRange(controls);
return controls.SelectMany(ctrl => GetAllChildControls(ctrl, list)).ToList();
}

internal static string GetSizeAndPositionOfControlsToString(Control container)
{
List<Control> controls = new List<Control>();
GetAllChildControls(container, controls);
CultureInfo cultureInfo = new CultureInfo("en");
string info = string.Empty;
foreach (Control control in controls)
{
info += control.Name + ":" + control.Left.ToString(cultureInfo) + "," + control.Top.ToString(cultureInfo) + "," +
control.Width.ToString(cultureInfo) + "," + control.Height.ToString(cultureInfo) + "*";
}
return info;
}
internal static void SetSizeAndPositionOfControlsFromString(Control container, string controlsInfoStr)
{
List<Control> controls = new List<Control>();
GetAllChildControls(container, controls);
string[] controlsInfo = controlsInfoStr.Split(new []{"*"},StringSplitOptions.RemoveEmptyEntries );
Dictionary<string, string> controlsInfoDictionary = new Dictionary<string, string>();
foreach (string controlInfo in controlsInfo)
{
string[] info = controlInfo.Split(new [] { ":" }, StringSplitOptions.RemoveEmptyEntries);
if (!controlsInfoDictionary.ContainsKey(info[0]))
{
controlsInfoDictionary.Add(info[0], info[1]);
}

}
foreach (Control control in controls)
{
string propertiesStr;
controlsInfoDictionary.TryGetValue(control.Name, out propertiesStr);
string[] properties = propertiesStr.Split(new [] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (properties.Length == 4)
{
control.Left = int.Parse(properties[0]);
control.Top = int.Parse(properties[1]);
control.Width = int.Parse(properties[2]);
control.Height = int.Parse(properties[3]);
}
}
}

#endregion
}
}

Winforms: Resizing user controls in form control

Forget about setting Dock and AutoSizeMode on your controls—just use Anchor and you will find it works just fine.

I never use AutoSize = true. I always have it at false (as a matter of fact I had to check some of my forms to verify that the AutoSize and AutoSizeMode properties even existed on controls on my forms).

In the scenario you describe, I would have the Anchor set to Top, Left, Bottom, Right, both for the panels and the controls contained within.

How to resize all controls on a form at run-time?

Trying using a TableLayoutPanel control with all rows and columns in percent mode.

new Form {
Controls = {
new TableLayoutPanel {
Dock = DockStyle.Fill,
ColumnCount = 2,
Controls = {
new Button {Text = "0,0", Dock = DockStyle.Fill},
new Button {Text = "1,0", Dock = DockStyle.Fill},
new Button {Text = "0,1", Dock = DockStyle.Fill},
new Button {Text = "1,1", Dock = DockStyle.Fill}
},
RowStyles = {
new RowStyle(SizeType.Percent) {Height = 1},
new RowStyle(SizeType.Percent) {Height = 1}
},
ColumnStyles = {
new ColumnStyle(SizeType.Percent) {Width = 1},
new ColumnStyle(SizeType.Percent) {Width = 1}
}
}
}
}.ShowDialog();


Related Topics



Leave a reply



Submit