I am dynamically creating controls on top of TabPages that are, of course, on a TabControl. I want to be able to dynamically dispose of these, too. How can I do that? Calling Clear on the TabControl's TabPages collection actually disposes the TabPages themselves, which defeats the purpose of "starting over" with new dynamically created controls on those pages.
Calling tabPageBla.Controls.Clear() is close to what I want, but it also disposes a container control that I have on each TabPage (FlowControlLayout) that I need to keep.
Is there a straightforward way to accomplish this (dispose only the dynamically-created controls, but not any of the others)?
Will this work - will grandchildren of TabControl1 also be found (children of the tab pages)?:
List<Control> ctrls = new List<Control>();
ctrls.AddRange(tabControl1.Controls);
foreach (var ctrl in ctrls)
{
// Controls named "panelRowBla", "richTextBoxBla", and "pictureBoxBla" need to be retained
string ctrlName = ctrl.Name;
if ((ctrlName.Contains("panelRow")) ||
(ctrlName.Contains("richTextBox")) ||
(ctrlName.Contains("pictureBox")))
{
continue;
}
}
That's odd; I could have sworn this was just compiling, but now I'm getting "Argument 1: cannot convert from 'System.Windows.Forms.Control.ControlCollection' to System.Collections.Generic.IEnumerable'"
(on the "AddRange()" line).
There is no way to tell if the control was created in the designer or dynamically. But what you can do, is to create a list of all the controls, which exist at the very start (controls which were created in the designer).
Create a new list to the class' root, to hold all the "original" controls:
List<Control> DesignerControls;
Use this modified PsychoCoder's method (https://stackoverflow.com/a/3426721/2538037) to list all controls (including controls inside controls):
public IEnumerable<Control> GetAll(Control control)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl))
.Concat(controls);
}
Before you have added any controls dynamically, run this line (for example in the constructor):
DesignerControls = GetAll(this).ToList();
Then add this static method for disposing the dynamically created controls:
public static bool DisposeDynamicObjects(List<Control> NonDynamicControls, List<Control> ControlsToDispose)
{
try
{
for (int i = 0; i < ControlsToDispose.Count; i++)
{
if (ControlsToDispose[i] != null &&
!ControlsToDispose[i].IsDisposed &&
!NonDynamicControls.Contains(ControlsToDispose[i]))
{
ControlsToDispose[i].Dispose();
--i;
}
}
return true;
}
catch (Exception ex) { MessageBox.Show(ex.Message); return false; }
}
When you want to dispose dynamically created controls, use this:
DisposeDynamicObjects(DesignerControls, GetAll(tabControl1).ToList());
The code above disposes all dynamically created controls inside tabControl1.Controls
. You can replace the tabControl1
with other controls, like this
for example, so all dynamically created controls are deleted from the whole form.