简体   繁体   中英

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. Basically i want a method like 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. The answers you've gotten so far are no exception. The Controls.Clear() and Controls.Remove() methods are very dangerous. 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". 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. Which also automatically removes them from the Controls collection.

Which is trap number two, you cannot use foreach to iterate the Controls collection. That disposes only the even numbered controls, a side effect of the collection getting modified by the foreach loop. 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. 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,

    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. For a GroupBox clear could mean recursively clear its controls. 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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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