如何处理动态创建的控件? [英] How can I dispose of dynamically created controls?
问题描述
我在TabPage顶部(当然在TabControl上)动态创建控件.我也希望能够动态处理这些.我怎样才能做到这一点?实际上,在TabControl的TabPages集合上调用Clear会自行处理TabPages,这违背了在这些页面上动态创建的新控件重新开始"的目的.
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.
调用tabPageBla.Controls.Clear()与我想要的很接近,但是它也将容器控件放置在我需要保留的每个TabPage(FlowControlLayout)上.
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)?
这项工作将会成功吗-还会找到TabControl1的孙子(标签页的子孙)吗?:
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;
}
}
更新2
这很奇怪;我本可以发誓这只是编译,但现在我得到"参数1:无法从'System.Windows.Forms.Control.ControlCollection'转换为System.Collections.Generic.IEnumerable'"
(在"AddRange()"行上).
(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).
在类的根目录中创建一个新列表,以保存所有原始"控件:
List<Control> DesignerControls;
使用经过修改的PsychoCoder方法( https://stackoverflow.com/a/3426721/2538037 )列出所有控件(包括控件内部的控件):
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);
}
动态添加任何控件之前,请运行以下行(例如在构造函数中):
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
,以便从整个表单中删除所有动态创建的控件.
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.
这篇关于如何处理动态创建的控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!