12

This happens a lot: I have a lot of controls laid out, and I decide I'd like to put them into a panel for whatever reason -- maybe to make it easier to disable them all at once without affecting other controls, or to isolate some radio buttons, etc.

I find it a cumbersome operation to add a System.Windows.Forms.Panel "beneath" my controls. This usually involves resizing my parent control or form so I can add the panel in a temporary space adjacent to the collection of controls that will soon occupy the panel, then dragging the controls onto the panel, then setting the parent control/form size back to what it was before.

Often I have anchors set in various ways on various controls so that simply resizing the parent doesn't happen without the carefully-tweaked layout of the controls getting all messed up.

This is obviously a tedious process for what should be such a simple operation. Is there a VS trick to doing this (other than editing the designer-generated file by hand, which would mean I'd have to hand-pick the controls by name that I want to re-parent)?

Matt
  • 25,467
  • 18
  • 120
  • 187
rory.ap
  • 34,009
  • 10
  • 83
  • 174
  • 2
    Not that I have found. At the risk of seeming overly critical, it really comes down to thoughtful planning of the form before building. – DonBoitnott May 30 '14 at 14:06
  • 1
    @DonBoitnott -- That's a nice thought for theoretical software development, but in practice that would require 100% impeccable fore-site. Also, it could be out of one's control (e.g. customer changes their mind). – rory.ap May 30 '14 at 14:19
  • 1
    Perhaps, but your comment "This happens a lot" suggests either a lack of planning or really bad luck. – DonBoitnott May 30 '14 at 14:21
  • @DonBoitnott Touché. But, then, I've never claimed to have impeccable fore-site :) – rory.ap May 30 '14 at 14:22
  • I'll admit it's happened to me a few times too. Which why I now rarely layout a form that doesn't begin with either a `Panel` or a `TableLayoutPanel`. Heavy on the latter. – DonBoitnott May 30 '14 at 14:27
  • Far simpler than playing the Designer games you did, is just manually editing the *.Designer.cs file. Add/size the panel, move the this.Controls.Add(btn) to panel1.Controls.Add(btn) ... etc... – John Arlen May 30 '14 at 21:02
  • Just place a `Panel` when you like (above your controls). Right click on `Panel` and `Send to back`. Then using `Ctrl+Click` select those controls which you like to move, drag them and drop into the panel. That's all, easy and straightforward. – Reza Aghaei Aug 05 '19 at 08:40

3 Answers3

11

There is no direct way, but a workaround available (Visual Studio 2010 - 2022):

Suppose you have a form named Form1.cs and there are already controls on it, such as a linkLabel, checkBoxes, radioButtons and a progressBar.

The trick is to edit the *.Designer.cs file instead of moving the controls around. Do the following:

  1. Place the new panel (panel1) on Form1 like you would normally do it (by using the toolbox), and give it a size so it covers the other controls.

  2. Close the form (and all related files), then activate in the solution explorer "Show all Files". Now Form1.Designer.cs becomes visible. Open it.

  3. Locate the following code, it contains the controls being registered to the form:

         // 
         // Form1
         // 
         this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
         this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
         this.ClientSize = new System.Drawing.Size(284, 262);
         this.Controls.Add(this.progressBar1);
         this.Controls.Add(this.linkLabel1);
         this.Controls.Add(this.panel1);
         this.Controls.Add(this.checkBox1);
         this.Controls.Add(this.radioButton1);
         this.Controls.Add(this.btnOk);
         this.Name = "Form1";
         this.Text = "Form1";
         this.panel1.ResumeLayout(false);
         this.panel1.PerformLayout();
         this.ResumeLayout(false);
         this.PerformLayout();
    

Then, look for the code that creates the panel:

        // 
        // panel1
        // 
        this.panel1.Location = new System.Drawing.Point(12, 12);
        this.panel1.Name = "panel1";
        this.panel1.Size = new System.Drawing.Size(260, 198);
        this.panel1.TabIndex = 7;

All you need to do is to move the controls from the form's Controls collection (this.Controls) to the panel's Controls collection (this.panel1.Controls). Move it from one place to the other in the source code, then use ** Alt+Shift ** (the block edit mode in Visual Studio's editor - hold the keys before you start selecting, and release them after you've selected the entire block) to replace this.Controls by this.panel1.Controls:

BlockEditAnimation and the only remaining controls being added to the form are panel1 and the ok button btnOk:

        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 262);
        this.Controls.Add(this.panel1);
        this.Controls.Add(this.btnOk);
        this.Name = "Form1";
        this.Text = "Form1";
        this.panel1.ResumeLayout(false);
        this.panel1.PerformLayout();
        this.ResumeLayout(false);
        this.PerformLayout();

Finally, close Form1.Designer.cs and re-open the form by double-clicking on Form1.cs. Now you should see the controls inside the panel. The positions are the same as they were before.


Note: This description was made for Visual Studio, if you're using Visual Studio Code instead, you can achieve the same with the multi cursor selection: Keyboard shortcuts are:  Strg+Alt+Arrow Up  or  Strg+Alt+Arrow Down . Alternatively you can select, and then press  Ctrl+Shift+L  to add multiple cursors to all occurances of the current selection. With multiple cursors, anything you type will be inserted/overwritten on all cursor positions.

Matt
  • 25,467
  • 18
  • 120
  • 187
  • 1
    Thanks for this. I haven't been able to get any work done for the last year because I've just been waiting for someone to answer this question :) My boss is really mad at me. But in all seriousness, thanks. – rory.ap Apr 09 '15 at 15:02
  • 3
    You're welcome. You know, you helped me recently, so I thought let's pick one of your unanswered questions and answer them. That is what drives Stackoverflow and makes it so powerful. :-) – Matt Apr 10 '15 at 06:33
  • Hey man, were you aware of the behavior Dave Hampel just described in his answer? It's blowing my mind! – rory.ap Oct 12 '19 at 13:20
  • @rory.ap - Yep, 3 years after my answer, Dave came up with that nice trick! By the way, I upvoted his answer. However, the answer I gave gives you some insight how the designer organizes the controls you place on the form... from time to time, I also needed to patch some things there. – Matt Oct 14 '19 at 14:14
  • Oh oops, I somehow mixed up Dave's answer and the new one by Gen1-1 from a couple days ago which is what I meant by my last comment. Dave's is good, but you should definitely check that other one out; it's the easiest way thus far. – rory.ap Oct 15 '19 at 12:13
  • @Matt: An upvote for introducing the Block-Edit Mode to me. ;) – D J Apr 09 '20 at 13:59
  • @DJ - Thank you, glad to hear it was useful for you! :-) – Matt Apr 11 '20 at 09:27
8

Matt has a pretty good answer but this might be a little easier.

Place a panel on your form and set Dock to full. You will not be able to see any of your controls. Then open the Document Outline for the form. Drag and drop each control onto Panel1. Each control will land right where you want them to be. Now if you wanted to, you could disable all controls in the panel by simply setting Panel1.Disabled = true.

If there are controls that you don't want to have as part of the panel. Select the control in the Document Outline and choose Bring to Front. This control will be visible and not affected by setting the panels Enable property.

Dave Hampel
  • 160
  • 3
  • 13
  • 1
    Dave, the advantage of the answer I gave is it works fast if you have a lot of controls to move (say, more than 10). If you have just a few, your answer is great (and also keeps the screen positions). Thanks! I upvoted your answer. One hint: "Bring to front" is not in document outline, it is directly in the form editor (context menu). – Matt Oct 09 '18 at 08:07
  • 1
    TIL that Document Outline was a thing. Thanks. – Chris Berger Mar 20 '19 at 18:45
  • This solution is soo much easier then messing around with the designer file! – Geert Bellekens Aug 28 '19 at 13:10
  • Where can one find Document Outline? – Brian Davis Feb 19 '20 at 15:11
  • 1
    Aha, I found it: View => Other Windows => Document Outline (Ctrl+Alt+T) – Brian Davis Feb 19 '20 at 15:17
7

This occasionally happens to me too, where I change my mind and want existing controls to now be in a panel (or some other container...GroupBox, FlowLayout, etc.).

Most of the time, the answer provided by Microsoft works well for me, and is documented here: Reassign Existing Controls to a Different Parent

Instead of dragging the container control to the form, you "draw" the outline of the container control around the existing controls, and then the container will grab the existing controls and make them children.

Steps:

  1. In the Toolbox, click to select the container control you want to use, then let go of the mouse button. Do NOT drag the control to the form.
  2. Move the mouse to the form area where your existing controls are, and notice the pointer changes to a crosshair, with the icon of whatever new container control you have selected.
  3. Hold the mouse button down, then drag and draw the outline of the new control "around" the existing controls. Be careful to completely surround all controls; if you get the border of the new container control too close to a control, there's a chance the existing control won't get included.
  4. Let go of the mouse button.

That's it. The existing controls should now be children of your container. I know it works in VS 2015 and newer, but I'm guessing it works for at least several versions before that.

Gen1-1
  • 424
  • 5
  • 9
  • Woah, I've *never* known this, after all these years! How long has it worked like this? – rory.ap Oct 12 '19 at 13:19
  • @rory.ap I've used it in VS 2015 and later, but I'm guessing it's been around for longer than that. – Gen1-1 Oct 12 '19 at 19:42
  • argh i can't believe i didn't just try this. ah well. definitely the right answer if your version of VS's form designer supports it. thank you. – shelleybutterfly Jul 13 '22 at 19:39