User resizable control.

J

Jay Dee Thompson

User resizable control.

In order to make a control that the user can resize by dragging the
edges of the control I have added MouseDown, MouseUp and MouseMove
events that allow the user to alter the size of the control.

This is a small example of what I mean allowing the user to drag the
right edge of the control.

<code>

private bool reSizeRight = false;

private Point lastMousePosition;

private void control_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (e.X > this.Width - this.Margin.Right)
{
this.reSizeRight = true;
}
}
}

private void control_MouseUp(object sender, MouseEventArgs e)
{
this.reSizeRight = false;
}

private void control_MouseMove(object sender, MouseEventArgs e)
{
if (this.reSizeRight)
{
int offset = e.X - this.lastMousePosition.X;
if (offset != 0)
{
this.Width += offset;
}
}
this.lastMousePosition = e.Location;
}

</code>

Then my next task was to be able to resize the control when it was
docked to either the right or the left side of its parent.

Dock.Left was simple by just adding an “If” statement to the code
above checking the controls dock property was “left”.

My problem.

If the control is docked to the right and I increase/decrease the
width of the control then the right edge of the control stays in the
same place and the left edge of the control will move accordingly.

This would all be good but the MouseMove event is repeatedly re-
occurring in a loop.

I think that it is because the control is being re positioned by the
MouseMove method yet the mouse is staying in the same place therefore
the mouse in relation to the control has changed, so the MouseMove
event is being re triggered.

I hope that makes sense I carnet think of a good way to explain.

I have tried un-hooking the method from the MouseMove event before
resizing the width then re-hooking the method back to the event call
but it had no effect.

Please ask if someone thinks I should post more code to help explain
the issue, I didn’t want to make the post any bigger.
 
J

Josh Einstein

With a bit more work (ok I'm downplaying that) you can actually host the
Windows Forms designer surface in your application, giving you the exact
same design time experience you'd get from Visual Studio or SharpDevelop.

http://www.divil.co.uk/net/articles/designers/hosting.asp

The above URL explains how in more detail.

But if you proceed with your current approach, you might want to check out
the Control.Capture property and handle the mouse events in a outer parent
control instead of in the control being moved.

Josh Einstein
 
J

Jay Dee Thompson

(Peter Duniho wrote)
If you had actually "un-hooked" the handler from the event, how could it
be called?

This question had me stuck for a little while, I had written:

<code>

this.MouseMove -= new MouseEventHandler(this.control_MouseMove);
this.Width += offset;
this.MouseMove -= new MouseEventHandler(this.control_MouseMove);

</code>

I had un-hooked the event, made the modification then re-hooked the
event.
Unfortunately the event is not called until a call to
“Application.DoEvents();“ witch was being called after I had re-hooked
the event again.

This corrected the problem:

<code>

this.MouseMove -= new MouseEventHandler(this.control_MouseMove);
this.Width += offset;
Application.DoEvents();
this.MouseMove += new MouseEventHandler(this.control_MouseMove);

(Peter Duniho wrote)
That said, as far as your specific question goes, it seems to me that if
you handle the mouse event from the parent control rather than the control
you're actually trying to resize, that might work better.

I set up a small text project to try this out but I can not understand
how this will help.
It is possible to resize a control from the event call of its parent
control but I must test for the area surrounding the control rather
than the area just inside the control as the event is not invoked once
the mouse actually enters the chilled control to be resized.

Indeed this eliminated the problem of the looped event call but it
created problems of its own. For example if two controls were added,
one Dock.Left and one Dock.Right then there parent MouseMove event
will never occur because the entire surface is covered by the chilled
controls.

Am I missing something?


(Josh Einstein wrote)
With a bit more work (ok I'm downplaying that) you can actually host the
Windows Forms designer surface in your application, giving you the exact
same design time experience you'd get from Visual Studio or SharpDevelop.

Although this did not really help with my current problem I learnt a
lot from it. Thank you.


I have actually overcome the issue now, thank you both for your help.

Rather than obtaining the offset from the diferance between the
position of the curcer at presont an the position the last time the
event method was rased like this

int offset = e.X – this.lastMousePosition.X;

I obtained the offset using a different approach and it eliminated the
problem, well to an extent.

int offset = -(this.Control.Width - e.X);

now when the event method is called the second time it calculates an
ofset of zero so the width is not changed the second time witch then
in turn douse not call the event the third time.

It probably isent perfect but it now works. Thank you all.

Jay Dee
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top