C# 如何处置动态创建的控件?

C# 如何处置动态创建的控件?,c#,winforms,dynamic,dispose,C#,Winforms,Dynamic,Dispose,我在TabPages上动态创建控件,当然,这些控件位于TabControl上。我也希望能够动态地处理这些。我该怎么做?在TabControl的TabPages集合上调用Clear实际上会处理TabPages本身,这与在这些页面上动态创建新控件“重新开始”的目的背道而驰 调用tabPageBla.Controls.Clear()与我想要的非常接近,但它也会处理我需要保留的每个TabPage(FlowControlLayout)上的容器控件 是否有一种简单的方法来实现这一点(只处理动态创建的控件,而

我在TabPages上动态创建控件,当然,这些控件位于TabControl上。我也希望能够动态地处理这些。我该怎么做?在TabControl的TabPages集合上调用Clear实际上会处理TabPages本身,这与在这些页面上动态创建新控件“重新开始”的目的背道而驰

调用tabPageBla.Controls.Clear()与我想要的非常接近,但它也会处理我需要保留的每个TabPage(FlowControlLayout)上的容器控件

是否有一种简单的方法来实现这一点(只处理动态创建的控件,而不处理任何其他控件)

使现代化 这是否有效?是否也会找到TabControl1的孙子(选项卡页面的子项)?:

List ctrls=new List();
ctrls.AddRange(tabControl1.Controls);
foreach(ctrls中的var ctrl)
{
//名为“panelRowBla”、“richTextBoxBla”和“pictureBoxBla”的控件需要保留
字符串ctrlName=ctrl.Name;
如果((ctrlName.Contains(“panelRow”))||
(ctrlName.Contains(“richTextBox”))||
(ctrlName.Contains(“pictureBox”))
{
持续
}
}
更新2 这很奇怪;我可以发誓这只是编译,但现在我得到了“参数1:无法从'System.Windows.Forms.Control.ControlCollection'转换为System.Collections.Generic.IEnumerable'”


(在“AddRange()”行上)。

如果从父控件中删除控件,则可以显式地
处置它,即:

 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();
}
var toRemove=tabControls1
.控制
.Cast()
其中(c=>!(c.Name.Contains(“panelRow”)| | c.Name.Contains(“richTextBox”)| | c.Name.Contains(“pictureBox”))
.ToList();
foreach(toRemove中的var c)
{
tabControls1.控件.移除(c);
((IDisposable)c).Dispose();
}

这将从
选项卡Control1
中删除与过滤器不匹配的所有控件。

如果从父控件中删除该控件,则可以显式地
处置它,即:

 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();
}
var toRemove=tabControls1
.控制
.Cast()
其中(c=>!(c.Name.Contains(“panelRow”)| | c.Name.Contains(“richTextBox”)| | c.Name.Contains(“pictureBox”))
.ToList();
foreach(toRemove中的var c)
{
tabControls1.控件.移除(c);
((IDisposable)c).Dispose();
}

这将从
选项卡Control1
中删除与过滤器不匹配的所有控件。

无法判断控件是在设计器中创建的还是动态创建的。但是,您可以做的是创建一个所有控件的列表,这些控件一开始就存在(在设计器中创建的控件)

为类的根目录创建一个新列表,以保存所有“原始”控件:

List<Control> DesignerControls;
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());
然后添加此静态方法来处理动态创建的控件:

List<Control> DesignerControls;
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
中所有动态创建的控件。您可以将
选项卡Control1
替换为其他控件,例如
,因此所有动态创建的控件都将从整个表单中删除。

无法判断控件是在设计器中创建的还是动态创建的。但是,您可以做的是创建一个所有控件的列表,这些控件一开始就存在(在设计器中创建的控件)

为类的根目录创建一个新列表,以保存所有“原始”控件:

List<Control> DesignerControls;
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());
然后添加此静态方法来处理动态创建的控件:

List<Control> DesignerControls;
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
中所有动态创建的控件。您可以将
选项卡Control1
替换为其他控件,例如
,以便从整个表单中删除所有动态创建的控件。

抱歉-添加了“Winforms”标记。抱歉-添加了“Winforms”标记。不过,我需要一种方法来循环它们,因为可能有一个Google复杂的控件。@B.ClayShannon只需在
parent.controls
(即:
var toRemove=parent.controls.ToList();
)中保留控件的本地副本,然后删除每个控件。作为一个有趣的补充;使用今天的当前系统,您将获得一个
OutOfMemoryException
尝试实例化googleplex控件:P@ErikPhilips:很可能;在个人层面上,我得到了一个OOME试图记住我昨天午餐吃了什么。通过使用
Dispose()
控件从其当前父控件的Control.ControlCollection中删除。不过,我需要一种方法来循环它们,因为可能有一个Google复杂的控件。@B.ClayShannon只需在
parent.controls
(即:
var toRemove=parent.controls.ToList();
)中保留控件的本地副本,然后删除每个控件。作为一个有趣的补充;使用今天的当前系统,您将获得一个
OutOfMemoryException
尝试实例化googleplex控件:P@ErikPhilips:很可能;在个人层面上,我得到了一个OOME试图记住我昨天午餐吃了什么。通过使用
Dispose()
控件从其当前父控件的Control.ControlCollection中删除。谢谢;我将“tabPage1”更改为“tabControl1”(希望这就是你的意思-但这似乎可以在不将控件从视线中移除的情况下处置控件-我需要为此调用Refresh或其他类似的方法吗?我用一些新代码更新了答案。这是一种使用方法。我更新了
DisposedDynamicObjects()
-方法的参数类型。请复制并使用此新版本。另请注意
.Cast().ToList()
。您可以使用递归方法列出控件内的所有控件,包括GroupBox及其控件。这里有一个链接:。您可以像这样使用它:
De