Έτσι στα πεταχτά σου δείχνω ένα παράδειγμα του τι μπορεί να σημαίνει ενεργό UserControl. Όλα στο παράδειγμα είναι στατικά και χωρίς interfaces.
Α) η μαμά φόρμα
(Γραφικά, φαντάσου 2 κουμπιά αριστερά και ένα άδειο panel δεξιά)
namespace MultiCustomControlChooser
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private UserControl m_myActiveControl = null;
private void button1_Click(object sender, EventArgs e)
{
if (m_myActiveControl != null)
m_myActiveControl.Dispose();
m_myActiveControl = new MyCustomControl1();
panel1.Controls.Add(m_myActiveControl);
}
private void button2_Click(object sender, EventArgs e)
{
if (m_myActiveControl != null)
m_myActiveControl.Dispose();
m_myActiveControl = new MyCustomControl2();
panel1.Controls.Add(m_myActiveControl);
}
}
}
Β) UserControl αντικείμενα που αναφέρονται παραπάνω
public partial class MyCustomControl1 : UserControl
{
public MyCustomControl1()
{
InitializeComponent();
Populate();
}
private void Populate()
{
checkBox1.Checked = true;
checkBox2.Checked = false;
checkBox3.Checked = false;
}
}
public partial class MyCustomControl2 : UserControl
{
public MyCustomControl2()
{
InitializeComponent();
Populate();
}
private void Populate()
{
label1.Text = "First";
label2.Text = "Second";
label3.Text = "Third";
}
}
Με λίγα λόγια η μαμά έχει ένα μέλος (member variable) UserControl, και ένα Control container, το panel1. To να κάνεις ένα UserControl Visible σημαίνει ότι πρέπει να δημιουργήσεις ένα από κάθε είδος (new MyCustomControl1(), new MyCustomControl2(), new MyCustomControl3(), κλπ.) και να έχεις ένα μηχανησμό που να έχει μόνο ένα ορατό κάθε χρονική στιγμή. Πέραν του ότι έτσι χαλάει η εντροπία του σύμπαντος και θα πέσει ο ουρανός στα κεφάλια μας, όλα αυτά τα αντικείμενα κάθονται στη μνήμη και την ξοδεύουν άσκοπα. Το panel1 έχει ένα ControlCollection στο οποίο μπορείς άνετα να κάνεις Add() όπως δείχνω, και Remove() όταν δεν το χρειάζεσαι.
Αν και δεν είμαι απόλυτα σίγουρος, το Remove() θα θέσει αυτόματα το αντικείμενο σε Disposable state, οπότε στην επόμενη γύρα ο σκουπιδιάρης (GarbageCollector) θα το συμμαζέψει. Για σιγουριά (εγώ ή εσύ ο ίδιος) πρέπει να τρέξω π.χ. το πρόγραμμα σε Debug mode βήμα-βήμα και να βλέπω το GDI Object count στον TaskManager.
Σκέψου για λίγο πώς θα μπορούσε κανείς να έχει προγραμματίσει τον Internet Explorer/ Firefox. Κάθε καινούριο Tab που προσθέτεις σημαίνει ότι γίνεται κάτι παρόμοιο με το παραπάνω παράδειγμα. Μια διαφορά είναι ότι αντί για ένα UserControl member, o Explorer θα είχε ένα List<UserControl> m_lstTabs, όπου καλεί την Add/Remove.
Panagiotis Georgiadis
HBM Netherlands B.V.
www.twitter.com/HimWithCurls