Search code examples
c#.netvisual-studiowinformsvisual-studio-2019

How to place a new panel underneath existing controls?


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


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:

    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.