visual studio - C# Copy controls from one form to another programmatically - Stack Overflow

admin2025-04-17  2

I have 2 forms for 2 different resolution displays. I need a way to select at run time the correct form for the current resolution. It does not change once the software is running.

Eg, I have a 1920x1080 layout and a 1280x800 layout. I created the mainform as the 1920x1080 display and a second form for the same controls and same names as the 1280x800 but adjust to fit the smaller resolution with different positions and font sizes.

The controls are all laid out in a Panel called mainPanel for each of the 2 forms. The component names are the same.

When I run the code and need to select the 1280x800, I remove and dispose of the mainPanel after also removing the events for the controls. I then add the second Form mainPanel to the existing form. This seems to work when I run the code as the smaller layout now appears but I cannot access the controls. It's as if the originals are still there. The component names are the same and the original layout to suit the 1920x1080 is not visible, just the copy but I cannot attach events to the buttons or update any text boxes.

This is the code I use to dispose of the existing components and add the new ones. Event removal and adding not included.

        mainPanel.Controls.Clear();
        mainPanel.Dispose();
        //
        // Set the size of the window
        //
        Width = 1280;
        Height = 740;

        smallScreenForm = new SmallScreenForm();

        this.Controls.Add(smallScreenForm.mainPanel);

I have 2 forms for 2 different resolution displays. I need a way to select at run time the correct form for the current resolution. It does not change once the software is running.

Eg, I have a 1920x1080 layout and a 1280x800 layout. I created the mainform as the 1920x1080 display and a second form for the same controls and same names as the 1280x800 but adjust to fit the smaller resolution with different positions and font sizes.

The controls are all laid out in a Panel called mainPanel for each of the 2 forms. The component names are the same.

When I run the code and need to select the 1280x800, I remove and dispose of the mainPanel after also removing the events for the controls. I then add the second Form mainPanel to the existing form. This seems to work when I run the code as the smaller layout now appears but I cannot access the controls. It's as if the originals are still there. The component names are the same and the original layout to suit the 1920x1080 is not visible, just the copy but I cannot attach events to the buttons or update any text boxes.

This is the code I use to dispose of the existing components and add the new ones. Event removal and adding not included.

        mainPanel.Controls.Clear();
        mainPanel.Dispose();
        //
        // Set the size of the window
        //
        Width = 1280;
        Height = 740;

        smallScreenForm = new SmallScreenForm();

        this.Controls.Add(smallScreenForm.mainPanel);
Share Improve this question asked Feb 1 at 4:42 Dave McLaughlinDave McLaughlin 415 bronze badges 6
  • 2 Your problem is not copying the control. The major problem is the design when you develop a form layout for a fixed screen size. The only reasonable design is fluid, when a form adjusts the alignment dynamically as the user changes the size. Even if you want to make it not resizable by the user. – Sergey A Kryukov Commented Feb 1 at 13:51
  • 1 I agree. @DaveMcLaughlin for winforms, maybe look at FlowLayoutPanel or TableLayoutPanel. – IV. Commented Feb 1 at 14:08
  • @IV — ...and the internals of the form depend on the content and requirements. Based on the information given, we cannot discuss it. The panels you suggested may or may not be applicable. In all cases, fluid design is possible and required. By the way, in WPF it is more natural and easy; basically, the design nearly automatically comes out fluid. – Sergey A Kryukov Commented Feb 1 at 15:00
  • 1 You might also want to start using the Dock property (though it might be a bit challenging to use for this specific case). If you know in advance you're only ever going to work on two resolutions, you might want to adjust max size and min size to all your controls according to the desired sizes for each resolution and then all you have to do is run a loop on your form's controls collection and adjust the size to either min or max size depending on the resolution chosen. You will need to use recursion if you have container controls, though. – Zohar Peled Commented Feb 1 at 18:56
  • @SergeyAKryukov even when I agree with you (as I just did), you disagree with me. Why is that? Anyway, as far as your mentioning WPF goes, I believe that it's a reasonable and fair assumption that when a question has posted under winforms tag that the OP has weighed their options and chosen WinForms to develop on. – IV. Commented Feb 3 at 12:21
 |  Show 1 more comment

2 Answers 2

Reset to default 0

Thanks all for your input. I found a solution. I create the SmallScreenForm and then I iterate through the controls in the mainform and do a Find on the controls in the SmallScreenForm being careful to check for child controls. I then copy the width, height, location and font settings from SmallScreenForm to the mainForm controls. Those are the only attributes that were change and hey presto, it works. After all have been set I dispose of the SmallScreenForm.

Probably not the best way to do it, but this is a single application system running my software only. At least now I can support some of the more popular small screens for those who cannot or won't purchase a PC with FULLHD display.

I didn't see any description about rebinding events in your account. Even if smallScreenForm.mainPanel is correctly added to this.Controls, controls like buttons still won't respond to clicks if you don't rebind the events. Moreover, according to your description, you use LargeScreenForm by default and, if a change is needed, destroy it and replace it with the SmallScreenForm you need. This approach will result in high code coupling, making it difficult to modify or extend. I suggest you create a MainForm(), a LargeScreenPanel, and a SmallScreenPanel. Then use the panel in the MainForm to switch between different resolutions.

In MainForm.cs:

 public partial class MainForm : Form
 {
/// <param name="useSmallScreenLayout">useSmallScreenLayout or not</param>
    public MainForm(bool useSmallScreenLayout)
    {
        InitializeComponent();
 
         if (useSmallScreenLayout)
        {
            SwitchToSmallLayout();
        }
        else
        {
            SwitchToLargeLayout();
        }
    }
 
    /// <summary>
    /// load large layout
    /// </summary>
    public void SwitchToLargeLayout()
    {
              if (currentPanel != null)
        {
           this.Controls.Remove(currentPanel);
            currentPanel.Dispose();
        }
            currentPanel = new LargePanel();
        currentPanel.Dock = DockStyle.Fill;
        this.Controls.Add(currentPanel);
       this.Width = 1920 / 2;
        this.Height = 1080 / 2;
        this.Text = "Large layout";
    }
 
    public void SwitchToSmallLayout()
    {
       // refer to SwitchToLargeLayout()
     }
}

In Program.cs:

           [STAThread]
           static void Main()
           {
                  bool useSmallScreenLayout = DetectSmallScreen();

// DetectSmallScreen() is the method which used to detect SmallScreen or LargeScreen.
 
              Application.Run(new MainForm(useSmallScreenLayout));
           }

In SmallPanel.cs/LargePanel.cs, Initialize all controls and bind events.

   internal class SmallPanel:Panel
   {
       public SmallPanel()
       {
 Button btn = new Button();
           btn.Name = "btnTest";
           btn.Text = "btnTest";
           btn.Font = new Font("Calibri", 8);
           btn.Size = new Size(100, 35);
           btn.Location = new Point(30, 30);
           btn.Click += Btn_Click;
           this.Controls.Add(btn);
       }

       private void Btn_Click(object sender, EventArgs e)
       {
           MessageBox.Show("Hello!");
       }
   }
转载请注明原文地址:http://anycun.com/QandA/1744839213a88338.html