Link to home
Start Free TrialLog in
Avatar of Lensolo
Lensolo

asked on

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.
Avatar of Lensolo
Lensolo

ASKER

My issues with MDI are discussed here. The solution works only if the child form retains the border:
https://www.experts-exchange.com/questions/28551587/c-child-mdi-does-not-maximize-with-parent.html
Avatar of it_saige
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-
Avatar of Lensolo

ASKER

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?
ASKER CERTIFIED SOLUTION
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
Avatar of Lensolo

ASKER

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.
Avatar of Lensolo

ASKER

Also, I did Anchor the panel to the top, bottom, left & right
Avatar of Lensolo

ASKER

Oh. I just saw your second comment. I'm trying to get this to happen on an event
Avatar of Lensolo

ASKER

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;
               }
            }
           
        }
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-
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Lensolo

ASKER

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();

        }
Avatar of Lensolo

ASKER

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.
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):User generated imageUser generated imageUser generated image
-saige-
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-