views:

393

answers:

4

Hello,

I have a canvas (Panel Control) in my WinForms app where users can drag things like textbox's, labels etc around. But I want to make it easier for them to more precisely align the objects. I've read into it and Adorners seem to be the way to go? But, apparently it's only for WPF. WPF is not an option for me, unfortunately.

What I'm trying to accomplish is to have lines pop up every time the user drags an object around in the canvas... Just how they work in the Windows Forms Designer View.

I'd appreciate any help at all.

Thank you.

A: 

There was a similiar question here: http://stackoverflow.com/questions/2211226/snap-to-lines-when-aligning-controls-at-runtime/2211261#2211261

Where I suggested something like:

left = (left/10)*10;
top = (top/10)*10;

For the snap part. Another user pointed to Form Desginer which might help you out.

Cory Charlton
Why the downvote? :-)
Cory Charlton
A: 

It is quite possible to do. Look at the DrawReversibleLine method on MSDN. In the meantime, I'll try to find some code in which I was doing the same thing.

bool AllowResize;
bool DoTracking;  

private void MyControl_MouseDown(object sender, MouseEventArgs e)
{
    if (AllowResize)
    {
        DoTracking = true;
                ControlPaint.DrawReversibleFrame(new Rectangle(this.PointToScreen(new Point(1,1)),
        this.Size), Color.DarkGray, FrameStyle.Thick);
    }
}

I know this is a very general & mostly crude start, but as mentioned, it can be a tedious task. Especially when it comes to tracking the movement, etc. Remember that on the MyControl_MouseUp event to call the ControlPaint.DrawReversibleFrame(...) to erase the frame. Also, during control movement. Calling the function again with the exact same parameters is all you need to to. Hope that helps.

Also, to reduce flicker, as Josh points out, add the following after your InitializeComponents();

//  To reduce redraw flicker
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
dboarman
+2  A: 

Thank you all for your answers.


I've managed to come up with my own solution. The code is down below. There are no "lines" yet, but I'll get around to it oneday...

Label l = (Label)sender;
foreach (Control control in Canvas.Controls)
{
    if (l.Location.X > control.Location.X + control.Size.Width && l.Location.X < control.Location.X + control.Size.Width + 5)
        l.Location = new Point(control.Location.X + control.Size.Width + 5, l.Location.Y);
    else if (l.Location.X < control.Location.X - l.Size.Width && l.Location.X > control.Location.X - l.Size.Width - 5)
        l.Location = new Point(control.Location.X - l.Size.Width - 5, l.Location.Y);
    else if (l.Location.Y > control.Location.Y + control.Size.Height && l.Location.Y < control.Location.Y + control.Size.Height + 5)
        l.Location = new Point(l.Location.X, control.Location.Y + control.Size.Height + 5);
    else if (l.Location.Y < control.Location.Y - control.Size.Height && l.Location.Y > control.Location.Y - control.Size.Height - 5)
        l.Location = new Point(l.Location.X, l.Location.Y - 5);

    this.Update();
}

The above code must be placed inside the Control_MouseMove Event, and ofcourse, you still need your own code that actually moves the controls.

The code above will snap the control you're dragging 5 pixels to the right, left, top or bottom of the nearest control.

lucifer
+1  A: 

If I understand correctly, you're looking to setup your control so that it act's kind of like the other container controls (GroupBox, Panel, etc)?

If so, I think DisplayRectangle is what you're after. You change it to the rectangle you want the other controls to snap to. For example, I have a GroupBox style control and I set the DisplayRectangle like so:

public override Rectangle DisplayRectangle
{
    get
    {
        return Rectangle.FromLTRB(base.DisplayRectangle.Left,
            base.DisplayRectangle.Top + Font.Height + 4,
            base.DisplayRectangle.Right,
            base.DisplayRectangle.Bottom);
    }
}

Now any control I place as a child will snap to that rectangle when I drag it toward the edges.

HTH!

Donald Beals
Very interesting!!!!!! Thank you, I will check it out :)
lucifer