Smooth Resize and Reposition
A demo on how to smoothly change the size or position of a Windows Form while holding down a button.
- Download SlideDemo project - 35.99 KB
- Download Form1 source - 1.46 KB
- Download Obscure project - 316.72 KB
In the image above, the cursor is held down on the top button, and the windows width enlarges smoothly to the right.
Introduction
This is a simple demonstration of how to smoothly resize or reposition a Windows Form by holding down a button. When the form is resized, the button and cursor remain in a constant position while the edge smoothly expands or contracts. When the form is repositioned, the cursor floats along on top of the button as it smoothly moves with the form.
Background
I was distracted by flashy advertising on a web site, and initially hid it under "Sticky Notes"; but that was unsatisfactory. Then I made a simple empty form with option "Top Most" set. That was awkward. What I wanted was something to slide just a bit right or grow just a bit taller. I came up with "Obscure", and worked on moving a window smoothly about while holding down one of several buttons. I thought it is worth sharing.
Using the Code
The key is one does not "Click" a button. The action is in a combination of MouseDown
, MouseUp
and a timer
event. There is a MouseDown
/Up
event for each button. The MouseDown
centers the cursor on an active control (button
) in followButton()
, sets a class enum
buttonPick
and enables a timer
. The button
might move the window or change its size.
If moving: in the timer
, a switch
branches on buttonPick
, and there changes the client and cursor origins by an incremental step.
If resizing: the switch
increments/decrements the current side of the window. Then, resets the client size via doResze()
.
In the little project "SlideDemo
", shown here and which you can download, one can only expand or contract the right side of the window. Or slide the window to the right. The project "Obscure
" is more complex. It allows one to move in 4 directions and expand and contract all 4 edges of the window. Plus, some other features.
MouseDown
/Up
events are very simple:
private void button_RightOut_MouseDown(object sender, MouseEventArgs e)
{
timer1.Enabled = true;
buttonPick = ButtonPick.RightOut;
}
private void button_RightOut_MouseUp(object sender, MouseEventArgs e)
{
buttonPick = ButtonPick.none;
timer1.Enabled = false;
}
The timer
handles the switch
on buttonPick
. You can see that SlideRight
changes the location of both the client and the cursor. While RightOut
only increments the width
of the client passing that onto doResize(width, height);
switch (buttonPick)
{
case ButtonPick.RightOut:
width += step;
// Keep the window from growing to wide
if (width > defaultWidthMax)
{
width = defaultWidthMax;
}
break;
case ButtonPick.SlideRight:
topX += step;
clientOrigin.Y = topY;
clientOrigin.X = topX;
this.Location = clientOrigin;
buttonsOrigin.X += step;
Cursor.Position = buttonsOrigin;
return;
...
}
doResize(width, height);
doResize()
is common code called at the end of the switch
to change the client's size.
private void doResize(int width, int height)
{
ignoreEvent = true;
this.ClientSize = new System.Drawing.Size(width, height);
ignoreEvent = false;
}
One must also handle two other Form
events, else the window may jump when you mouse down on a button.
private void Form1_LocationChanged(object sender, EventArgs e)
{
topX = Location.X;
topY = Location.Y;
}
private void Form1_ClientSizeChanged(object sender, EventArgs e)
{
if (ignoreEvent) return;
width = this.ClientSize.Width;
height = this.ClientSize.Height;
}
Points of Interest
Figuring out how to handle the mouse events in coordination with a timer was fairly easy. The handling of the LocationChanges and ClientSizeChanged
events was not so obvious. And the window kept jumping on me. In "Obscure
", I save form settings and allow the user to change the granularity of increments.
History
- Version 1.0