views:

696

answers:

3

In a program I have written users can add controls to the form and move them around and set some properties in a pseudo design mode. I want to be able to lock all these controls into one location when they press a button to switch to "data mode". How can I do this? I wanted to do be able to loop through all the controls and use the Lock Property but I noticed it didn't show up in intellisense.

Thanks!

+2  A: 

The Locked property is not a real property -- it is one which is added in by the Windows Forms designer (like the Generate Member and Modifiers "properties"). You would therefore need to simulate it yourself, either at the form level or (if required) at the control level (say with a dictionary of which controls are locked), and manually check it in the code you've written for moving controls around.

itowlson
+1  A: 

Locking controls prevents them from being dragged to a new size or location on the design surface. However, you can still change the size or location of controls by means of the Properties window or in code.

MSDN

I guess it's a visible-to-designer-only property. I think you'd have to implement your own freeze mechanism - a little flag to toggle between Design and Use modes.

Update: It seems that custom designer classes can add properties to controls based on whether they are in Design Mode or not.
More details available here if you intend to take the VS architectural hammer path. In any case, worth 10 mins of reading time.
Custom Design-time Control Features in Visual Studio .NET - Dino Esposito

Gishu
+1  A: 

Hi, I am assuming by "pseudo-design mode" you do mean that your application is in a run-time state, and the end-user is experiencing a "virtual design mode" : please correct me if I am wrong.

But, I am assuming you are referring to the design-time 'Locked property of controls, and that you wish to "emulate" this at run-time ... correct ?

I'm also assuming you are attaching mouse up/down/move handlers to the controls you do allow to move around, probably by looping through all, or a subset of, the controls on the form (or a collection you are maintaining of controls allowed to be moved).

If my assumptions are correct, I would go for removing the event handlers that enable moving when you need to disable control movement, then restoring those event handlers when you need to allow controls to be moved again.

One main reason being that it is, imho, "best practice" to control event-handling rigorously (leaving event handlers "in-place" can interfere with object disposal ... although that may, in no way, apply to your scenario here).

One more idea : you have an "invisible" Panel docked 'fill to the Form : on this panel are all controls that can be moved : this may allow you to more easily "narrow your focus" on which controls you "spend" this extra code on. The drawbacks in using this approach are usually :

  1. if you use hostingForm.ActiveControl to determine which control got the mousedown (and, thus, can then be moved) : you'll find some controls, like labels, and pictureboxes, do not become the activecontrol of the form when clicked, but most do.

  2. you have a "z-order" thing to think about since a control not in your panel encapsulating the controls you wish to allow to move sent behind the pseudo-transparent panel will be hidden.

For these reasons, imho, I think disabling and re-enabling event handler attachments is best, most simple, and since it can be done when the controls are "down-cast" to their control "identity" :

private void enableControlsMove()
{
    foreach (Control theControl in panel1.Controls)
    {
        Console.WriteLine(theControl.Name);

        theControl.MouseDown += new MouseEventHandler(theControl_MouseDown);
        theControl.MouseUp += new MouseEventHandler(theControl_MouseUp);
        theControl.MouseMove += new MouseEventHandler(theControl_MouseMove);
    }
}

private void disableControlsMove()
{
    foreach (Control theControl in panel1.Controls)
    {
        Console.WriteLine(theControl.Name);

        theControl.MouseDown -= theControl_MouseDown;
        theControl.MouseUp -= theControl_MouseUp;
        theControl.MouseMove -= theControl_MouseMove;
    }
}

I use it this way.

best, Bill

BillW
That is eventually what I did last night before reading this. It was simple and quick.
Nathan