How to Clear All Controls on a Form C#

What is the best way to clear all controls on a form C#?

What I have come up with so far is something like this:

public static class extenstions
{
private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() {
{typeof(TextBox), c => ((TextBox)c).Clear()},
{typeof(CheckBox), c => ((CheckBox)c).Checked = false},
{typeof(ListBox), c => ((ListBox)c).Items.Clear()},
{typeof(RadioButton), c => ((RadioButton)c).Checked = false},
{typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()},
{typeof(Panel), c => ((Panel)c).Controls.ClearControls()}
};

private static void FindAndInvoke(Type type, Control control)
{
if (controldefaults.ContainsKey(type)) {
controldefaults[type].Invoke(control);
}
}

public static void ClearControls(this Control.ControlCollection controls)
{
foreach (Control control in controls)
{
FindAndInvoke(control.GetType(), control);
}
}

public static void ClearControls<T>(this Control.ControlCollection controls) where T : class
{
if (!controldefaults.ContainsKey(typeof(T))) return;

foreach (Control control in controls)
{
if (control.GetType().Equals(typeof(T)))
{
FindAndInvoke(typeof(T), control);
}
}

}

}

Now you can just call the extension method ClearControls like this:

 private void button1_Click(object sender, EventArgs e)
{
this.Controls.ClearControls();
}

EDIT: I have just added a generic ClearControls method that will clear all the controls of that type, which can be called like this:

this.Controls.ClearControls<TextBox>();

At the moment it will only handle top level controls and won't dig down through groupboxes and panels.

how can we clear the all form controls on winform?

For TextBox and ComboBox

    public static void ClearSpace(Control control)
{
foreach (Control c in control.Controls)
{
var textBox = c as TextBox;
var comboBox = c as ComboBox;

if (textBox != null)
(textBox).Clear();

if (comboBox != null)
comboBox.SelectedIndex = -1;

if (c.HasChildren)
ClearSpace(c);
}
}

Usage:

        ClearSpace(this); //Control

Any way to clear all fields in a form at once?

You can use the following loop to clear all the textbox objects in your active form:

foreach (Control c in this.Controls) 
{
if (c.GetType() == typeof(TextBox))
{
c.Clear();
}
}

You can also use the loop inside a function and give it a Boolean return value to test if it was successfuly executed.

Remove all buttons from panel

Your list of controls is iterating to the half because the iterator increase while the amount of items are decrease. In the middle of the (internal) index of your Control-List is bigger than the amount of items.

Save the list of items first:

List<Button> buttons = panel.Controls.OfType<Button>().ToList();
foreach (Button btn in buttons)
{
btn.Click -= new EventHandler(this.b_Click); //It's unnecessary
panel.Controls.Remove(btn);
btn.Dispose();
}

edit: Why do you remove the Click-Event, if you dispose the button? After Disposing, the events are cleared and the button could not be used either.´

If you want a 1 line solution, you could only use Dispose. It will remove the buttons automatically from the panel an clear all events etc.

panel.Controls.OfType<Button>().ToList().ForEach(btn => btn.Dispose());

How to remove all controls except one?

An alternative to Rufus's solution if you know the names of the GroupBoxes that you want to exclude beforehand, you can use the Enumerable.Except() method:

foreach (var grp in Controls.OfType<GroupBox>().
Except(new[] { groupBox1, groupBox7 }).ToList())
{
Controls.Remove(grp);
}

Delete GroupBoxes

Clear all textboxes at once in winform

this method clear all textbox from WinForm

void ClearTextboxes(System.Windows.Forms.Control.ControlCollection ctrls)
{
foreach (Control ctrl in ctrls)
{
if (ctrl is TextBox)
((TextBox)ctrl).Text = string.Empty;
ClearTextboxes(ctrl.Controls);
}
}

and you can call it

private void btnReset_Click(object sender, EventArgs e)
{
ClearTextboxes();
txtFname.Focus();
}

Tabcontrol pages in C# clear all controls

First of all you have to decide what means "clear" for each kind of control. I.e. 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);
}

Removing dynamic controls from panel

You are still not saying which control you want to remove, what type of controls you want to remove or how you want to identify them.

You could just loop through the controls to remove specific Controls.

If you have Linq, its easy:

private void btn_Click(object sender, EventArgs e)
{
panel1.Controls.Clear(); //to remove all controls

//to remove all comboboxes
foreach (Control item in panel1.Controls.OfType<ComboBox>().ToList())
{
panel1.Controls.Remove(item);
}

//to remove control by Name
foreach (Control item in panel1.Controls.OfType<Control>().ToList())
{
if (item.Name == "bloodyControl")
panel1.Controls.Remove(item);
}


//to remove just one control, no Linq
foreach (Control item in panel1.Controls)
{
if (item.Name == "bloodyControl")
{
panel1.Controls.Remove(item);
break; //important step
}
}
}

Edit:

Its easy to do the same since you're tagging the control already. All you need is to just retrieve the control back from tag. But you need to tag appropriately:

Do this instead:

private void button1_Click(object sender, EventArgs e)
{
int v;
v = c++;
panel1.VerticalScroll.Value = VerticalScroll.Minimum;

Button btn = new Button();
btn.Name = "btn" + v;
btn.Text = "Remove";
btn.Location = new Point(750, 5 + (30 * v));
btn.Click += new EventHandler(btn_Click);

ComboBox combo = new ComboBox();
combo.Name = "combobox" + v ;
combo.Location = new Point(30, 5 + (30 * v));
combo.Tag = btn;

ComboBox combo2 = new ComboBox();
combo2.Name = "combobox2" + v ;
combo2.Location = new Point(170, 5 + (30 * v));
combo2.Tag = btn;

TextBox txt = new TextBox();
txt.Name = "txtbx" + v;
txt.Location = new Point(300, 5 + (30 * v));
txt.Tag = btn;

TextBox txt2 = new TextBox();
txt2.Name = "txtbx2" + v;
txt2.Location = new Point(450, 5 + (30 * v));
txt2.Tag = btn;

TextBox txt3 = new TextBox();
txt3.Name = "txtbx3" + v;
txt3.Location = new Point(600, 5 + (30 * v));
txt3.Tag = btn;

panel1.Controls.Add(combo);
panel1.Controls.Add(btn);
panel1.Controls.Add(txt);
panel1.Controls.Add(combo2);
panel1.Controls.Add(txt2);
panel1.Controls.Add(txt3);
}

private void btn_Click(object sender, EventArgs e)
{
//to remove control by Name
foreach (Control item in panel1.Controls.OfType<Control>().ToList())
{
if (item.Tag == sender || item == sender)
panel1.Controls.Remove(item);
}
}

Here you are tagging controls with the button, hence on the button click you can remove all the controls whose tags are the clicked button which you get from sender argument. But the downside of this approach is that you have to enumerate all the controls of the panel which is not great.

Edit: As I came to learn the below code is for a table layout panel which the OP isn't using for now. But anyway a table panel layout is better suited for this job.

I would suggest you to do this:

private void button1_Click(object sender, EventArgs e)
{
int v;
v = c++;
panel1.VerticalScroll.Value = VerticalScroll.Minimum;

Button btn = new Button();
btn.Name = "btn" + v;
btn.Text = "Remove";
btn.Location = new Point(750, 5 + (30 * v));
btn.Click += new EventHandler(btn_Click);
btn.Tag = v;

ComboBox combo = new ComboBox();
combo.Name = "combobox" + v ;
combo.Location = new Point(30, 5 + (30 * v));
combo.Tag = v;

ComboBox combo2 = new ComboBox();
combo2.Name = "combobox2" + v ;
combo2.Location = new Point(170, 5 + (30 * v));
combo2.Tag = v;

TextBox txt = new TextBox();
txt.Name = "txtbx" + v;
txt.Location = new Point(300, 5 + (30 * v));
txt.Tag = v;

TextBox txt2 = new TextBox();
txt2.Name = "txtbx2" + v;
txt2.Location = new Point(450, 5 + (30 * v));
txt2.Tag = v;

TextBox txt3 = new TextBox();
txt3.Name = "txtbx3" + v;
txt3.Location = new Point(600, 5 + (30 * v));
txt3.Tag = v;

panel1.Controls.Add(combo);
panel1.Controls.Add(btn);
panel1.Controls.Add(txt);
panel1.Controls.Add(combo2);
panel1.Controls.Add(txt2);
panel1.Controls.Add(txt3);
}

private void btn_Click(object sender, EventArgs e)
{
int toBeDeletedRow = (int)((Control)sender).Tag;
for (int row = panel1.RowCount - 1; row >= 0; row--)
{
if (row == toBeDeletedRow)
{
panel1.RowStyles.RemoveAt(row);
panel1.RowCount--;
return;
}
}
}


Related Topics



Leave a reply



Submit