简体   繁体   English

C#中的Tabcontrol页面清除所有控件

[英]Tabcontrol pages in C# clear all controls

I have a tab page that has text boxes, drop downs, check boxes, all of the above in group boxes and some labels. 我有一个选项卡页,其中包含文本框,下拉列表,复选框,以上所有内容在组框中和一些标签。 Now i want to clear all the controls when user clicks on a button. 现在,我想在用户单击按钮时清除所有控件。 How should i implement it? 我应该如何实施? I have searched a lot thinking there would be a standard library method. 我搜索了很多内容,认为会有一种标准的库方法。 All i found was some methods with for-each loops(which wont work inside group boxes.) Please guide me on how to proceed with this issue. 我发现的所有方法都是带有for-each循环的(在组框内不起作用。)请指导我如何解决此问题。 Basically i want a method like Tabpage.load(); 基本上我想要一个类似Tabpage.load()的方法; which takes the tab to its initial condition. 该选项卡将其恢复到初始状态。 if possible i want to preserve specific text boxes. 如果可能的话,我想保留特定的文本框。

A lot of Winforms programmers get this kind of code wrong. 许多Winforms程序员都会弄错这种代码。 The answers you've gotten so far are no exception. 到目前为止,您所获得的答案也不例外。 The Controls.Clear() and Controls.Remove() methods are very dangerous. Controls.Clear()和Controls.Remove()方法非常危险。 The methods remove the controls from their parent, as intended, but they don't dispose the controls. 这些方法按预期从其父级中删除了控件,但是它们并未处置这些控件。 They get rehosted on an internal hidden window named the "ParkingWindow". 他们被重新托管在名为“ ParkingWindow”的内部隐藏窗口中。 To keep the native window alive, ready to be moved to another parent window. 为了使本机窗口保持活动状态,可以将其移动到另一个父窗口。

That's a very nice feature, but unfortunately a major source of uncontrollable window handle leaks. 这是一个非常好的功能,但不幸的是,无法控制的窗口句柄泄漏的主要来源。 Because, by far, the actual intent is to dispose them, not rehost them. 因为到目前为止,实际意图是处置它们,而不是重新托管它们。 To remove a control permanently you must use their Dispose() method. 若要永久删除控件, 必须使用其Dispose()方法。 Which also automatically removes them from the Controls collection. 这也会自动将它们从Controls集合中删除。

Which is trap number two, you cannot use foreach to iterate the Controls collection. 这是第二个陷阱,您不能使用foreach来迭代Controls集合。 That disposes only the even numbered controls, a side effect of the collection getting modified by the foreach loop. 这仅设置了偶数编号的控件,该集合的副作用被foreach循环修改了。 You must iterate it backwards instead, like this: 您必须改为向后迭代,如下所示:

    public static void UnloadTabpage(TabPage page) {
        for (int ix = page.Controls.Count - 1; ix >= 0; --ix) {
            page.Controls[ix].Dispose();
        }
    }

Also, do not recurse like Justin did. 另外, 不要像递归贾斯汀一样。 Disposing a control automatically disposes any child controls of that control as well. 处置控件也会自动处置该控件的所有子控件。 Perhaps the problem with your group box, it isn't very clear. 也许您的分组框存在问题,但不是很清楚。

Just for kicks, here's another implementation that really drives the point home: 只是为了踢球,这是另一个真正使人明白的实现:

    public static void UnloadTabpage(TabPage page) {
        while (page.Controls.Count > 0) page.Controls[0].Dispose();
    }

But that doesn't easily let you remove controls selectively, like you mentioned you want to do. 但这并不能轻易让您有选择地删除控件,就像您提到的那样。

use the ControlCollection.Clear() method. 使用ControlCollection.Clear()方法。 MSDN MSDN

myTabControl.Controls.Clear()

If you want to preserve certain controls, you can either 如果要保留某些控件,则可以

  • Remove only the controls you need using enumeration and condition checking. 使用枚举和条件检查仅删除所需的控件。
  • Clear all controls and then readd only the ones you want to keep. 清除所有控件,然后仅读取要保留的控件。

It depends on how many controls you want to keep vs. how many you want to remove. 这取决于要保留的控件数量与要删除的控件数量。

This works for me, GroupBox included, 这对我有用,包括GroupBox,

    void ClearControls(Control parent)
    {
        while (parent.Controls != null && parent.Controls.Count > 0)
        {
            ClearControls(parent.Controls[0]);
            parent.Controls.Remove(parent.Controls[0]);
        }
    }

First of all you have to decide what means "clear" for each kind of control. 首先,您必须确定每种控件的“清除”含义是什么。 Ie it could mean set the text to strimg.Empty for the TextBox, set Checked to false for the CheckBox and do nothing for the Label. 也就是说,这可能意味着将文本设置为strimg.Empty,将TextBox设置为false,而对Label则不执行任何操作。 For a GroupBox clear could mean recursively clear its controls. 对于GroupBox,清除可能意味着递归清除其控件。 Once decided what you do you could define a delegate type and create a Dictionary of these delegates where the Type of the control is the key. 一旦决定了要做什么,就可以定义一个委托类型并创建这些委托的字典,其中控件的类型是关键。 Now you can loop on the control collection applying the right delegate. 现在,您可以应用正确的委托循环访问控件集合。 The code is simpler than the explanation: 代码比解释要简单:

public delegate void ClearControl(Control aCtrl);

private static Dictionary<Type, ClearControl> _clearDelegates;

public static Dictionary<Type, ClearControl> ClearDelegates
{
    get 
    { 
        if (_clearDelegates== null)
            InitializeClearDelegates();
        return _clearDelegates; 
    }
}

private static void InitializeClearDelegates()
{
    _clearDelegates= new Dictionary<Type, ClearControl>();
    _clearDelegates[typeof(TextBox)] = new ClearControl(delegate(Control aCtrl) 
    {
        ((TextBox)aCtrl).Text = string.Empty;
    });
    _clearDelegates[typeof(CheckBox)] = new ClearControl(delegate(Control aCtrl)
    {
        ((CheckBox)aCtrl).Checked = false;
    });
    _clearDelegates[typeof(GroupBox)] = new ClearControl(delegate(Control aCtrl)
    {
        foreach (Control innerCtrl in ((GroupBox)aCtrl).Controls)
            Clear(innerCtrl);
    });
    _clearDelegates[typeof(TabPage)] = new ClearControl(delegate(Control aCtrl)
    {
        foreach (Control innerCtrl in ((TabPage)aCtrl).Controls)
            Clear(innerCtrl);
    });
    // ... other controls
}

public static object Clear(Control aCtrl)
{
    ClearControl aDel;
    if (ClearDelegates.TryGetValue(aCtrl.GetType(), out aDel))
        aDel(aCtrl);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM