Glenn Angel Glenn Angel -3 years ago 92
C# Question

Panel with multiple forms, choose top most with button

SO i have a main menu with buttons down the side and a panel which is my "main display area" (panelactive).

When i click a button for a form to fill the panelactive i need the relating form to be displayed initiated and displayed top-most.
if it is active already i want it just to come to the TOP.

I had this code

Form g = Application.OpenForms["frmpackmenu"];

if (g == null)
{
frmpackmenu frmpackmenu = new frmpackmenu(topack, tocheck, total);
frmpackmenu.TopLevel = false;
panelactive.Controls.Add(frmpackmenu);
frmpackmenu.Dock = DockStyle.Fill;
frmpackmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frmpackmenu.Show();
}
else
{
g.Show();
}


But the issue here is that each form doesn't "hide" after the new form is called to fill the panel.

I did try VISIBLE which worked.. however it only works once the forms have been initaited.. however i dont want all forms initaited on startup as most likely only one form is going to be used by the user and i have a selection of 6, one of which is quite memory heavy.

SO i need to:


  1. Check if initiated

  2. If not, initiate and move to top

  3. If it is, just show it and hide the other initiated form so THAT doesnt have to reload later..



I have tried and i just can't wrap my head around how i can check all forms if they are there as well as make visible or not etc.

Or am i doing this all completely wrong??

Thansk for advice.
Gangel

Is doing a case statement and then doing this for ever case what i need to do??

if (collectmenu == null)
{
frmcollectmenu frmcollectmenu = new frmcollectmenu();
frmcollectmenu.TopLevel = false;
panelactive.Controls.Add(frmcollectmenu);
frmcollectmenu.Dock = DockStyle.Fill;
frmcollectmenu.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frmcollectmenu.Show();
}
else
{
collectmenu.Visible = true;
}
if (packmenu != null)
{
packmenu.Visible = false;
}
if (checkmenu != null)
{
checkmenu.Visible = false;
}

Answer Source

UserControl solution. This will test if your panel already has the control (by name - but you can modify this to use types, or literally anything you want.

Create a new project, and paste this in to the namespace block (I don't know what you'll name it. WindowsFormsApp1 maybe, or whatever).

I created everything dynamically so you don't need to mess with the designer to get it to work. It will log how many UC's are in the panel, so you know it's grabbing the existing one, and not creating a new one.

The key here is that with a UC, all you need to do is "BringToFront" and everything else is just handled for you. It will not create unneccessary ones. I believe this is what you want:

public partial class Form1 : Form
{
    Panel pnlMain;
    Panel pnlSelect;
    public Form1()
    {
        InitializeComponent();

        //You will already have all of this - this is just to make a minimal-complete example without the designer.
        pnlSelect = new Panel();
        pnlMain = new Panel();
        this.Controls.AddRange(new Control[] { pnlSelect, pnlMain });
        pnlSelect.Dock = DockStyle.Left;
        pnlMain.Dock = DockStyle.Right;
        pnlSelect.Width = (int)(this.Width * 0.2);
        pnlMain.Width = this.Width - pnlSelect.Width - 25;
        for(int i=0;i<6;i++)
        {
            Button btn = new Button();
            btn.Name = i.ToString();
            btn.Text = i.ToString();
            pnlSelect.Controls.Add(btn);
            btn.Location = new Point(btn.Location.X, btn.Height * i + 5);
            btn.Click += Btn_Click;
        }
        //just to see a difference
        pnlMain.BackColor = Color.Green;
    }

    private void Btn_Click(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        UserControl oCon = (from UserControl uc in pnlMain.Controls where uc.GetType() == typeof(UserControl) && uc.Name == btn.Name select uc).FirstOrDefault();
        if(oCon == null)
        {
            oCon = new UserControl();
            oCon.Name = btn.Name;
            pnlMain.Controls.Add(oCon);
            Label lbl = new Label();
            lbl.Text = oCon.Name;
            oCon.Controls.Add(lbl);
            //just to see a difference
            oCon.BackColor = Color.Blue;                
        }
        oCon.BringToFront();
        Console.WriteLine("pnlMain has: {0} Children.", pnlMain.Controls.Count.ToString());
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download