Luke Ireland Luke Ireland - 19 days ago 9
C# Question

C# Object Panels

The problem I'm having is where I can successfully use the RoomID of the Room object I've created, but not the panel. Here is the function where I set the label to the name of the room. (This is my Form1.cs)

public partial class Form1 : Form
{
Room ThisRoom = new Room();
public Form1()
{
InitializeComponent();
this.Text = "Aquinas College Master Controller";
}

private void roomDesignerToolStripMenuItem_Click(object sender, EventArgs e)
{
new RoomDesigner().Show();
}

private void button1_Click(object sender, EventArgs e)
{
roomsToolStripMenuItem.DropDownItems.Clear();
foreach (var Room in Global.Aquinas.Aquinas)
{
ToolStripMenuItem NewItem = new ToolStripMenuItem(Room.RoomID);
NewItem.Name = Room.RoomID;
NewItem.Click += new EventHandler(ItemClick);
roomsToolStripMenuItem.DropDownItems.Add(NewItem);
}
}

void ItemClick(object sender, EventArgs e)
{
ToolStripItem item = (ToolStripItem)sender;
label2.Text = item.Name;
foreach (var Room in Global.Aquinas.Aquinas)
{
if (Room.RoomID == item.Name)
{
ThisRoom = Room;
break;
}
}
Panel RoomPanel = ThisRoom.Panel;
RoomPanel.Size = new Size(607, 304);
RoomPanel.Location = new Point(144, 27);
RoomPanel.BackColor = Color.White;
this.Controls.Add(RoomPanel);
}
}


This is some of my code for the room object. (This is in Room.cs)

public class Room
{

private List<CtrlComputer> _Computers;

public List<CtrlComputer> Computers
{
get { return _Computers; }
set { _Computers = value; }
}

private string _RoomID;

public Room()
{
_Computers=new List<CtrlComputer>();
}

public string RoomID
{
get
{
return _RoomID;
}

set
{
_RoomID = value;
}
}

public Panel Panel
{
get
{
return _Panel;
}

set
{
_Panel = value;
}
}

private Panel _Panel;
}


And here is where I register the panel which I have just put my designs on, to a new room. (This is some of my RoomDesigner.cs)

public partial class RoomDesigner : Form
{
Room NewRoom = new Room();
Panel RoomDesignerPanel = new Panel();
public RoomDesigner()
{
InitializeComponent();
RoomDesignerPanel.Size = new Size(607, 304);
RoomDesignerPanel.Location = new Point(144, 27);
RoomDesignerPanel.BackColor = Color.White;
this.Controls.Add(RoomDesignerPanel);
textBox1.ForeColor = SystemColors.GrayText;
textBox1.Text = "Enter Computer ID Here";
this.textBox1.Leave += new System.EventHandler(this.textBox1_Leave);
this.textBox1.Enter += new System.EventHandler(this.textBox1_Enter);
textBox2.ForeColor = SystemColors.GrayText;
textBox2.Text = "Enter Room ID Here";
this.textBox2.Leave += new System.EventHandler(this.textBox2_Leave);
this.textBox2.Enter += new System.EventHandler(this.textBox2_Enter);
}

private void textBox1_Leave(object sender, EventArgs e)
{
if (textBox1.Text.Length == 0)
{
textBox1.Text = "Enter Computer ID Here";
textBox1.ForeColor = SystemColors.GrayText;
}
}

private void textBox1_Enter(object sender, EventArgs e)
{
if (textBox1.Text == "Enter Computer ID Here")
{
textBox1.Text = "";
textBox1.ForeColor = SystemColors.WindowText;
}
}
private void textBox2_Leave(object sender, EventArgs e)
{
if (textBox2.Text.Length == 0)
{
textBox2.Text = "Enter Room ID Here";
textBox2.ForeColor = SystemColors.GrayText;
}
}

private void textBox2_Enter(object sender, EventArgs e)
{
if (textBox2.Text == "Enter Room ID Here")
{
textBox2.Text = "";
textBox2.ForeColor = SystemColors.WindowText;
}
}


private void button1_Click(object sender, EventArgs e)
{
CtrlComputer NewComputer = new CtrlComputer();
NewComputer.ComputerID = textBox1.Text;
NewComputer.Text = NewComputer.ComputerID;
NewComputer.Parent = RoomDesignerPanel;
RoomDesignerPanel.Controls.Add(NewComputer);
NewRoom.Panel = RoomDesignerPanel;
NewRoom.Add(NewComputer);
}


When I try to reload that panel, the RoomID of that object is returned fine, yet the panel is not. Any ideas?

Edit: Sorry for the lack of clarity in my post, first posts aren't always easy.
The panel is created in the designer, but I tried
private Panel Panel1 = new Panel();
with no luck. My current problem is that in Form1.cs, the program will throw "Cannot access a disposed object", but I followed the guide here https://msdn.microsoft.com/en-us/library/82785s1h(v=vs.110).aspx .

Answer

What you are looking to do is swap between a collection of Panel objects (kind of like your own version of TabPages). To do this you need to create each of the Panel objects (You do this in RoomDesigner, which is fine, but there is a catch: see * below). With that collection in hand, when you want to show it on the form, you need to remove the panel1 the designer code created (Controls.Remove(panel1)) and insert your new one (Controls.Add(RoomPanel)).

Since Controls utilize system resources, make sure to Dispose any control you will no longer use. Here is an example method:

    //Initial case where no room has been displayed yet and panel1 is still valid
    private Panel CurrentPanel = null;

    public void SwapPanel(Panel p)
    {
        //If no panel has been placed yet, get rid of the default one
        if (panel1 != null)
        {
            //we should never need the designer panel again, so dispose it
            panel1.Dispose();
            this.Controls.Remove(panel1);
        }
        else
        {
            //we may return to this panel later, so don't dispose it
            this.Controls.Remove(CurrentPanel);
        }
        CurrentPanel = p;
        this.Controls.Add(p);
    }

When you finally close out and no longer need your Panels stored in your Room collection, make sure to Dispose them. (However, if your whole program is exiting at that point then it doesn't matter, but do it anyway as good practice)

*When you close any RoomDesigner form (or any form), all controls it contains in 'Controls' will be disposed, even if you are using them elsewhere. To prevent this, remove the controls you want to preserve from the RoomDesigner Controls collection before it is closed.

Comments