Click to See Complete Forum and Search --> : Painting and Invalidating


mrs
November 21st, 2004, 01:37 PM
I am trying to drag and resize controls during runtime with the same look and feel that VS does it. I paint the Handles and Selection Frames when a control gets the focus. However I need to remove them when the control loses focus. The Control_LostFocus function does not remove them. However, if I set a break point in the Control_Lostfocus function and them step out, the handles and Frame are removed. Why does break point do this? How can I resolve this issue?

ControlsHash is a Hash table containing the controls.

Thanks

Matt


private void Control_GotFocus(Object sender, EventArgs e) {
// Retrieve related info
Control c = (Control) sender;
ControlInfo info = (ControlInfo) ControlsHash[c];
if(info.Enabled) {
//Resizable rectangle
Rectangle rectOutside = new Rectangle(c.Location.X-6, c.Location.Y-6, c.Width+12, c.Height+12);
Rectangle rectInside = new Rectangle(c.Location.X, c.Location.Y, c.Width, c.Height);
ControlPaint.DrawSelectionFrame(GraphicPainter, true, rectOutside, rectInside, Color.Transparent);

Rectangle rect = new Rectangle(c.Location.X-8, c.Location.Y-8, 8, 8);
ControlPaint.DrawGrabHandle( GraphicPainter, rect, true, true);
rect.X = (c.Width-8)/2+ c.Location.X;
ControlPaint.DrawGrabHandle( GraphicPainter, rect, true, true);
rect.X = c.Width + c.Location.X;
ControlPaint.DrawGrabHandle( GraphicPainter, rect, true, true);

rect.X = c.Location.X-8;
rect.Y = c.Location.Y + c.Height;
ControlPaint.DrawGrabHandle( GraphicPainter, rect, true, true);
rect.X = (c.Width-8)/2+ c.Location.X;
ControlPaint.DrawGrabHandle( GraphicPainter, rect, true, true);
rect.X = c.Width + c.Location.X;
ControlPaint.DrawGrabHandle( GraphicPainter, rect, true, true);
}
}

private void Control_LostFocus(Object sender, EventArgs e) {
Control c = (Control) sender;
Rectangle rectOutside = new Rectangle(c.Location.X-8, c.Location.Y-8, c.Width+16, c.Height+16);
c.Invalidate(rectOutside);
c.Update();
}

atkin
November 22nd, 2004, 12:15 AM
Hi
I think I was having the same problem, when you say the change happens when you break into the code. Its not actually that, it when you lose focus. Instead of breaking into the code, just do an alt - tab and this should give you the same results.
If it does then this means that the control needs updating, you should call its invalidate method and that should fix the problem.
I havent looked at your code just your message.
Good luck

Norfy
November 22nd, 2004, 05:07 AM
Hi mrs,

I'm not surprised you get different behaviour during debugging. Even in a debug session events still get fired to your controls, eg. Invalidate(), which may not be going just to the control you are debugging.

I see in your GotFocus handler you are drawing to a GraphicPainter object. Have you tried Invalidate() on the control that contains the Graphics object for this. I'm not sure if you can Invalidate an area bigger than the control itself.

mrs
November 22nd, 2004, 06:47 AM
Thanks for your reply...

The GraphicsPainter object is the form's graphics. I am painting the grab handles and the SelectionRectangle on the form the button sits on.

You did give me an idea. You said:

Have you tried Invalidate() on the control that contains the Graphics object for this.

That's what my LostFocus function is doing now...invalidating the control but with the form's graphic object. However, it works if I invalidate the form:

private void Control_LostFocus(Object sender, EventArgs e) {
Control c = (Control) sender;
c.Parent.Invalidate();
}

I now need to figure out how to make the code more robust and reusable.

I am trying to make a provider to give this drag/resize functionality. When it's done I'll send it to you.

Thank you for suggestion/helping,

Matt

Norfy
November 22nd, 2004, 07:22 AM
Invalidate() is relative to the Control that invokes it. ie. For control.Invalidate() this is equivalent to control.Invalidate(new Rectangle(0, 0, control.Width, control.Height)). To invalidate the same area via the parent you would call control.Parent.Invalidate(control.Bounds).

With your previous code you were invalidating an area that was in the wrong coordinates. Whether control.Invalidate(new Rectangle(-8, -8, c.Width+16, c.Height+16) would work I have no idea.

mrs
November 22nd, 2004, 08:59 AM
FYI:

I just tried:

control.Invalidate(new Rectangle(-8, -8, c.Width+16, c.Height+16)

and it didn't work.

Once again,

Thanks,

Matt

Norfy
November 22nd, 2004, 09:33 AM
No problem, I accept all major credit cards...but failing that you could always click on the Rate This Post link. :)

FunkyMofo
December 3rd, 2004, 08:47 PM
Try using the OnEnter and OnLeave methods instead.