如何处理动态创建的控件? [英] How can I dispose of dynamically created controls?

查看:61
本文介绍了如何处理动态创建的控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆