Non-MDI way to Load Windows forms into panel on parent form

I want to build a windows forms application that is all within one form with a menu strip at the top that loads custom built panels into a designated panel on the form. Currently I have 3 panels built on the parent form that I show hide that fill the screen seamlessly, but I have to add abouty 10 more of these, so I want to see if I can accomplish the exact same effect by loading a form instead of a panel so I don't have to maintain this layered panel nightmare.

I have tried the MDI approach, but it seems like this is designed for bordered, movable windows. I can't get these to load seamlessly without a boder or top bar that minimized & maximizes with the parent form. I don't think they were designed for this. So, I want to regroup & ask what the "correct" way is to accomplish the same thing.  

NOTE: I am using C# .net 4.3 framework with Visual Studio 2012 to design this.
LensoloAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

LensoloAuthor Commented:
My issues with MDI are discussed here. The solution works only if the child form retains the border:
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_28551587.html
0
it_saigeDeveloperCommented:
I'm having difficulty fully understanding what your goal is.  It might be easier to accomplish what you are wanting by extending the Panel class (in either a user control or component class) so that you can implement properties and events that control the hiding and showing of the panels.

-saige-
0
LensoloAuthor Commented:
I may not be explaining it well. If you were creating a windows appliction & want to have 1 main form with a menu strip on top that the user will use to load 10-15 other forms on demand. Each child form will fill the parent window when it loads & must be borderless as if you actually created the objects directly onto the parent window. The child forms are pretty complex with grids, charts, text boxes, etc. How will you go about it?
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Fernando SotoRetiredCommented:
Hi Lensolo;

To place a form with in a panel of another form can be accomplished as follows.
Create a Windows form without a title bar and add the form to the panel control as follows.

// Create an instance of the form to be placed in the Panel control
var f2 = new Form2();
// Remove the Title bar and form borders
f2.FormBorderStyle = Windows.Forms.FormBorderStyle.None;
// Make the form the same size as the panel it is to be placed in
f2.Size = Panel1.Size;
// Remove the TopLevel attribute of the form, a form within another form needs this to be false
f2.TopLevel = false;
// Add the form to the panel
Panel1.Controls.Add(f2);
// Show the form
f2.Show();

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Fernando SotoRetiredCommented:
Hi Lensolo;

Also be advised that when you resize the main form you're going to have to scale down or scale up this form to correctly fit the panel otherwise it will be clipped or have more space around it then needed.
0
LensoloAuthor Commented:
Thanks. That works great except color the background of the child differently than the parent & make it smaller than the parent. You will see that it initially fills the parent when it loads. Then click Maximixe on the parent window & you will see the maximize issue.
0
LensoloAuthor Commented:
Also, I did Anchor the panel to the top, bottom, left & right
0
LensoloAuthor Commented:
Oh. I just saw your second comment. I'm trying to get this to happen on an event
0
LensoloAuthor Commented:
The best way I know to forceably resize this is on the panel resize event. The panel is resizing, but the child form loaded into it is not. I am missing something with this code. If I add a background color change to both the panel & the child form. The panel color changes, but the child form background color doesn't change. This may be my only issue. If I can determine how to contrl the child object on resize I have what I need.


  private void panel1_Resize(object sender, EventArgs e)
        {
            Form frm = null;
            this.panel1.BackColor = Color.PaleVioletRed;

            foreach (Control contr in this.panel1.Controls)
            {
              if (contr.GetType() == typeof(Form))
                {
                  frm = (Form)contr;
                  frm.Size = Parent.Size;
                  frm.BackColor = Color.Red;
               }
            }
           
        }
0
it_saigeDeveloperCommented:
This works for me:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Drawing;

namespace CSharpExample
{
		/// <summary>Initializes a new instance of the <see cref="Form1"/> class.</summary>
		public Form1()
		{
			InitializeComponent();
		}

		/// <summary>Handles the <see cref="E:Load" /> event.</summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
		private void OnLoad(object sender, EventArgs e)
		{
			// Create an instance of the form to be placed in the Panel control
			var f2 = new Form2();
			// Remove the Title bar and form borders
			f2.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
			// Make the form the same size as the panel it is to be placed in
			f2.Size = panel2.Size;
			// Remove the TopLevel attribute of the form, a form within another form needs this to be false
			f2.TopLevel = false;
			// Add the form to the panel
			panel2.Controls.Add(f2);
			// Show the form
			f2.Show();
		}

		/// <summary>Handles the <see cref="E:Resize" /> event.</summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
		private void OnResize(object sender, EventArgs e)
		{
			if (sender is Panel)
			{
				Panel pnl = sender as Panel;
				foreach (Control control in pnl.Controls)
				{
					if (control is Form)
					{
						Form frm = control as Form;
						frm.Size = pnl.Size;
						frm.BackColor = Color.Red;
					}
				}
			}
		}
	}
}

Open in new window


-saige-
0
Mike TomlinsonMiddle School Assistant TeacherCommented:
As I said before, you need to set the Dock style of the form to Fill:

    someDynamicForm.Dock = DockStyle.Fill;

It'll work, assuming the Panel itself (that the form is being added to) has been properly setup to resize with the form.

If this doesn't help, then please post pictures of how it isn't working.  That'll probably help us figure out what direction the solution needs to go in...
0
LensoloAuthor Commented:
Mike. That was the missing element. I tried it on the other post & didn't have luck, but it seems to be working now with Fernando Soto's code as shown. Thank you guys very much!  

  private void fParentTest2_Load(object sender, EventArgs e)
        {
            // Create an instance of the form to be placed in the Panel control
            var f2 = new fChildTest2();
            // Remove the Title bar and form borders
            f2.FormBorderStyle = FormBorderStyle.None;
            // Make the form the same size as the panel it is to be placed in
            f2.Size = panel1.Size;

            // Remove the TopLevel attribute of the form, a form within another form needs this to be false
            f2.TopLevel = false;
           f2.Dock = DockStyle.Fill;
           // Add the form to the panel
            panel1.Controls.Add(f2);
            // Show the form
            f2.Show();

        }
0
LensoloAuthor Commented:
it_saige, Thanks you for your response, but I created 2 new forms & tried what you sent & it did not work for me. This is resolved now though, but thank you.
0
it_saigeDeveloperCommented:
Full code -

Form1.cs -
using System;
using System.Drawing;
using System.Windows.Forms;

namespace EE_Q28554300
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void OnClick(object sender, EventArgs e)
		{
			if (sender is Button)
			{
				Button btn = sender as Button;
				if (btn == btnAdd)
				{
					// Create an instance of the form to be placed in the Panel control
					var f2 = new Form2()
					{ 
						/* Remove the Title bar and form borders*/
						FormBorderStyle = System.Windows.Forms.FormBorderStyle.None, 
						/* Make the form the same size as the panel it is to be placed in*/
						Size = pnlForms.Size, 
						/* Remove the TopLevel attribute of the form, a form within another form needs this to be false*/
						TopLevel = false
					};
					// Add the form to the panel
					pnlForms.Controls.Add(f2);
					// Show the form
					f2.Show();
				}

				if (btn == btnRemove)
				{
					foreach (Control control in pnlForms.Controls)
					{
						if (control is Form)
						{
							Form frm = control as Form;
							frm.Close();
							frm.Dispose();
							frm = null;
						}
					}
				}
			}
		}

		private void OnResize(object sender, EventArgs e)
		{
			if (sender is Panel)
			{
				Panel pnl = sender as Panel;
				foreach (Control control in pnl.Controls)
				{
					if (control is Form)
					{
						Form frm = control as Form;
						frm.Size = pnl.Size;
						frm.BackColor = Color.Red;
					}
				}
			}
		}
	}
}

Open in new window


Form1.Designer.cs -
namespace EE_Q28554300
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.pnlNavigation = new System.Windows.Forms.Panel();
			this.lblNavigation = new System.Windows.Forms.Label();
			this.pnlForms = new System.Windows.Forms.Panel();
			this.lblForms = new System.Windows.Forms.Label();
			this.pnlFooter = new System.Windows.Forms.Panel();
			this.btnRemove = new System.Windows.Forms.Button();
			this.btnAdd = new System.Windows.Forms.Button();
			this.pnlNavigation.SuspendLayout();
			this.pnlForms.SuspendLayout();
			this.pnlFooter.SuspendLayout();
			this.SuspendLayout();
			// 
			// pnlNavigation
			// 
			this.pnlNavigation.Controls.Add(this.lblNavigation);
			this.pnlNavigation.Dock = System.Windows.Forms.DockStyle.Left;
			this.pnlNavigation.Location = new System.Drawing.Point(0, 0);
			this.pnlNavigation.Name = "pnlNavigation";
			this.pnlNavigation.Size = new System.Drawing.Size(200, 332);
			this.pnlNavigation.TabIndex = 0;
			// 
			// lblNavigation
			// 
			this.lblNavigation.AutoSize = true;
			this.lblNavigation.Location = new System.Drawing.Point(63, 175);
			this.lblNavigation.Name = "lblNavigation";
			this.lblNavigation.Size = new System.Drawing.Size(75, 13);
			this.lblNavigation.TabIndex = 1;
			this.lblNavigation.Text = "This is panel 1";
			// 
			// pnlForms
			// 
			this.pnlForms.Controls.Add(this.lblForms);
			this.pnlForms.Dock = System.Windows.Forms.DockStyle.Fill;
			this.pnlForms.Location = new System.Drawing.Point(200, 0);
			this.pnlForms.Name = "pnlForms";
			this.pnlForms.Size = new System.Drawing.Size(384, 332);
			this.pnlForms.TabIndex = 1;
			this.pnlForms.Resize += new System.EventHandler(this.OnResize);
			// 
			// lblForms
			// 
			this.lblForms.AutoSize = true;
			this.lblForms.Location = new System.Drawing.Point(155, 175);
			this.lblForms.Name = "lblForms";
			this.lblForms.Size = new System.Drawing.Size(75, 13);
			this.lblForms.TabIndex = 1;
			this.lblForms.Text = "This is panel 2";
			// 
			// pnlFooter
			// 
			this.pnlFooter.Controls.Add(this.btnRemove);
			this.pnlFooter.Controls.Add(this.btnAdd);
			this.pnlFooter.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.pnlFooter.Location = new System.Drawing.Point(0, 332);
			this.pnlFooter.Name = "pnlFooter";
			this.pnlFooter.Size = new System.Drawing.Size(584, 30);
			this.pnlFooter.TabIndex = 2;
			// 
			// btnRemove
			// 
			this.btnRemove.Location = new System.Drawing.Point(487, 4);
			this.btnRemove.Name = "btnRemove";
			this.btnRemove.Size = new System.Drawing.Size(85, 23);
			this.btnRemove.TabIndex = 1;
			this.btnRemove.Text = "Remove Form";
			this.btnRemove.UseVisualStyleBackColor = true;
			this.btnRemove.Click += new System.EventHandler(this.OnClick);
			// 
			// btnAdd
			// 
			this.btnAdd.Location = new System.Drawing.Point(396, 4);
			this.btnAdd.Name = "btnAdd";
			this.btnAdd.Size = new System.Drawing.Size(85, 23);
			this.btnAdd.TabIndex = 0;
			this.btnAdd.Text = "Add Form";
			this.btnAdd.UseVisualStyleBackColor = true;
			this.btnAdd.Click += new System.EventHandler(this.OnClick);
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(584, 362);
			this.Controls.Add(this.pnlForms);
			this.Controls.Add(this.pnlNavigation);
			this.Controls.Add(this.pnlFooter);
			this.Name = "Form1";
			this.Text = "Form1";
			this.pnlNavigation.ResumeLayout(false);
			this.pnlNavigation.PerformLayout();
			this.pnlForms.ResumeLayout(false);
			this.pnlForms.PerformLayout();
			this.pnlFooter.ResumeLayout(false);
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.Panel pnlNavigation;
		private System.Windows.Forms.Label lblNavigation;
		private System.Windows.Forms.Panel pnlForms;
		private System.Windows.Forms.Label lblForms;
		private System.Windows.Forms.Panel pnlFooter;
		private System.Windows.Forms.Button btnRemove;
		private System.Windows.Forms.Button btnAdd;
	}
}

Open in new window


Form2.cs -
using System.Windows.Forms;

namespace EE_Q28554300
{
	public partial class Form2 : Form
	{
		public Form2()
		{
			InitializeComponent();
		}
	}
}

Open in new window


Form2.Designer.cs -
namespace EE_Q28554300
{
	partial class Form2
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.label1 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// label1
			// 
			this.label1.AutoSize = true;
			this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.label1.Location = new System.Drawing.Point(77, 119);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(131, 24);
			this.label1.TabIndex = 2;
			this.label1.Text = "I am form 2!!!";
			// 
			// Form2
			// 
			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.label1);
			this.Name = "Form2";
			this.Text = "Form2";
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private System.Windows.Forms.Label label1;

	}
}

Open in new window


Gives me your expected results (I believe):First launchForm addedForm resized.
-saige-
0
it_saigeDeveloperCommented:
No worries, I didn't have an example created that I could show and just really quick bound the OnResize event to another project I had to see if I could produce the same results you were getting.  My initial code response was just saying that I was able to replicate your expected results.  The code I posted above is a complete working example project.

-saige-
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.