How to place a new panel underneath existing controls?

.net, c#, visual-studio, visual-studio-2019, winforms

Solution

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:

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.

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

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`:

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.

Problem

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)?

Original source