我在TabPages上动态创建控件,当然是在TabControl上。我希望能够动态处理这些。我怎样才能做到这一点?在TabControl的TabPages集合上调用Clear实际上会释放TabPages本身,这会使这些页面上新动态创建的控件“重新开始”的目的失效。
调用tabPageBla.Controls.Clear()接近我想要的,但是它还处理了我需要保留的每个TabPage(FlowControlLayout)上的容器控件。
有没有直接的方法来实现这一点(只处理动态创建的控件,但不处理任何其他控件)?
这是否有效 - 是否还会找到TabControl1的孙子(标签页的子项)?:
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;
}
}
那很奇怪;我可以发誓这只是编译,但现在我得到“参数1:无法从'System.Windows.Forms.Control.ControlCollection'转换为System.Collections.Generic.IEnumerable'”
(在“AddRange()”行上。)
答案 0 :(得分:4)
如果从父级删除控件,则可以显式Dispose
,即:
parent.Controls.Remove(theControl);
((IDisposable)theControl).Dispose();
鉴于您的编辑,您应该能够:
var toRemove = tabControls1
.Controls
.Cast<Control>()
.Where(c => !(c.Name.Contains("panelRow") || c.Name.Contains("richTextBox") || c.Name.Contains("pictureBox")))
.ToList();
foreach(var c in toRemove)
{
tabControls1.Controls.Remove(c);
((IDisposable)c).Dispose();
}
这将删除tabControl1
中与您的过滤器不匹配的所有控件。
答案 1 :(得分:1)
无法判断控件是在设计器中创建还是动态创建。但你可以做的是创建一个控件的列表,这些控件一开始就存在(控件在设计器中创建)。
为班级创建一个新列表&#39; root,持有所有&#34;原创&#34;控制:强>
List<Control> DesignerControls;
使用此修改后的PsychoCoder方法(https://stackoverflow.com/a/3426721/2538037)列出所有控件(包括控件内的控件):
public IEnumerable<Control> GetAll(Control control)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl))
.Concat(controls);
}
在动态添加任何控件之前,请运行此行(例如在构造函数中):
DesignerControls = GetAll(this).ToList();
然后添加此静态方法来处理动态创建的控件:
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; }
}
如果要处置动态创建的控件,请使用:
DisposeDynamicObjects(DesignerControls, GetAll(tabControl1).ToList());
上面的代码将所有动态创建的控件都放在tabControl1.Controls
中。您可以将tabControl1
替换为其他控件,例如this
,以便从整个表单中删除所有动态创建的控件。