//list the controls from the main form
foreach (Control c in Controls)
{
if (c is ComboBox)
{
((ComboBox)c).SelectedIndex = -1;
}
else if (c is TextBox)
{
((TextBox)c).Text = "";
}
else if (c is CheckBox)
{
((CheckBox)c).Checked = false;
}
//etc. with FIFTY different types to check against
}
Asked
Active
Viewed 213 times
5
-
well in C# 7 (in development) it can certainly solve a problem like this... but for today's version, not so much. – Ahmed ilyas Oct 30 '15 at 17:11
-
1what is the goal here? – USER_8675309 Oct 30 '15 at 17:11
-
i need to do this job for 50 controls .... – fre3land Oct 30 '15 at 17:12
-
2@fre3land You have 50 *types* of controls, or 50 controls of these three types? If you have 50 different *types*, then yes, you really need a better pattern, if you have 50 controls of these three types, the code you have should be sufficient. – Servy Oct 30 '15 at 17:13
-
50 types of controls sir. – fre3land Oct 30 '15 at 17:14
-
@M.kazemAkhgary It is, however, a bit annoying to read through as the programmer. – Mage Xy Oct 30 '15 at 17:17
-
@M.kazemAkhgary True, and it looks like Domysee had the same (`?.`) idea so I'm deleting the comment. – 31eee384 Oct 30 '15 at 17:17
-
You can also remove the `{ }` of your `if`-statements and the enters – H. Pauwelyn Oct 30 '15 at 17:23
3 Answers
9
One way is to add three overloaded methods for specific types, cast to dynamic
, and make calls like this:
foreach (dynamic c in Controls) {
ClearOut(c);
}
...
private static void ClearOut(ComboBox c) {
c.SelectedIndex = -1;
}
private static void ClearOut(TextBox t) {
t.Text = string.Empty;
}
private static void ClearOut(CheckBox c) {
c.Checked = false;
}
Since c
is dynamic
, C# would postpone binding of the ClearOut
method to runtime, giving you a clean-looking code. The downside of this approach is that C# is unable to tell you at compile-time if one of the overloads is missing.

Sergey Kalinichenko
- 714,442
- 84
- 1,110
- 1,523
-
I don't see why dynamic is needed if all those types derive from `Control`. – Erik Philips Oct 30 '15 at 17:16
-
really nice. i didnt know this. but 50 methods isnt going to be short – M.kazem Akhgary Oct 30 '15 at 17:16
-
-
2@ErikPhilips If you use `Control` for `c`'s type, C# would try to make a method binding at compile time, and fail, because there is no overload of `ClearOut` that takes `Control`. – Sergey Kalinichenko Oct 30 '15 at 17:19
-
-
2"50 methods wont be short" True , but sometimes that is the best you can get. Also, it is better to handle it per item, then go through 50 checks every time. – Casey ScriptFu Pharr Oct 30 '15 at 17:22
-
-
1@M.kazemAkhgary That's because you've got a control on the list that has no corresponding method, right? You can catch this situation by adding an overload that takes `Control`, and setting a breakpoint. – Sergey Kalinichenko Oct 30 '15 at 17:47
-
1you are a genius. yeah i forgot i had button control. it works great now. – M.kazem Akhgary Oct 30 '15 at 17:48
6
Use this method to set the properties of your controls:
public void Set(object obj, string property, object value)
{
//use reflection to get the PropertyInfo of the property you want to set
//if the property is not found, GetProperty() returns null
var propertyInfo = obj.GetType().GetProperty(property);
//use the C# 6 ?. operator to only execute SetValue() if propertyInfo is not null
propertyInfo?.SetValue(obj, value);
}
Call it like this:
foreach (Control c in Controls)
{
Set(c, "SelectedIndex", -1);
Set(c, "Text", "");
Set(c, "Checked", false);
}

Domysee
- 12,718
- 10
- 53
- 84
-
1
-
2
-
@AIG - indeed, it is so its a perf issue here. I also need to point out that this works for C# 6+ – Ahmed ilyas Oct 30 '15 at 17:21
-
@AlG yes it will. I admit its a performance issue, but not all operations have to watch for every CPU cycle – Domysee Oct 30 '15 at 17:21
-
-
This is wrong. because `.?` can return null and you cant have null at left side of assignment. thus compile time error. – M.kazem Akhgary Oct 30 '15 at 17:30
-
-
-
-
1Why not store everything in a data structure, and then exit out of the for loop as soon as a match is found and run? – Emil Oct 30 '15 at 18:01
3
You can create a lookup from each supported type to an action that clears controls of that type, you can then add handlers to that lookup for each supported type:
public class ControlClearer
{
private static Dictionary<Type, Action<Control>> lookup = new Dictionary<Type, Action<Control>>();
static ControlClearer()
{
AddMapping((TextBox control) => control.Text = "");
AddMapping((ComboBox control) => control.SelectedIndex = -1);
AddMapping((CheckBox control) => control.Checked = false);
}
private static void AddMapping<T>(Action<T> clearAction)
where T : Control
{
lookup[typeof(T)] = control => clearAction((T)(object)control);
}
public static void Clear<T>(T control)
where T : Control
{
//todo support case where T isn't in the dictionary
lookup[typeof(T)](control);
}
public static void Clear(Control control)
{
//todo support case where the type isn't in the dictionary
lookup[control.GetType()](control);
}
}

Servy
- 202,030
- 26
- 332
- 449