-1

I have this code which casts controls to a TextBox:

foreach (Control c in Controls)
    if (c.GetType() == typeof(TextBox))
        (c as TextBox).Clear();

And I would like to encapsulate it in a function, where I pass in the type at runtime. Something like this:

public void ControlClear(ControlCollection controls, Type type) {
      foreach (Control c in controls)
          if (c.GetType() == type)
              (c as ([?])).Clear();
}
ControlClear(Controls, typeof(TextBox));

How can I cast to the type like this?

David
  • 208,112
  • 36
  • 198
  • 279
이재국
  • 5
  • 3
  • 2
    There are only three types of controls that have a Clear() method, ListView, RichTextBox and TextBox. So trying to make it universal is not very useful, you don't actually need the Type argument. Guessing at what you *really* want to do: resetting the content of a Form is very easy. Just create a new instance of it. If that causes your program to terminate too early then [look here](https://stackoverflow.com/a/10769349/17034). – Hans Passant Jun 16 '18 at 12:16
  • What if somebody passes `Button` and you call `Clear`? – usr Jun 16 '18 at 12:37

4 Answers4

2

This will work for you.

you have to check if the type is not the wanted type, there is a chance that is another container so you have to run the method for the control to be sure not missing any type of control in another container but in same form.

Your method should be like :

public void ControlClear(Control controls,Type type)
        {
            foreach (Control c in controls.Controls)
            {
                if (c.GetType() == type)
                {
                    MessageBox.Show("true"); // Do whatever you want here. Since not all controls have Clear() method, consider using Text=string.Empty; or any other method to clear the selected type.
                }
                else
                {
                    ControlClear(c, type); // fire the method to check if the control is a container and has another type you are targeting.
                }

            }

        }

Then call it like :

ControlClear(this,typeof (TextBox)); // this refers to Current form. You can pass a groupBox, panel or whatever container you want.
Kaj
  • 806
  • 6
  • 16
2

use this code:

    public void ControlClear(Control.ControlCollection controls, Type type)
    {
        foreach (Control c in controls)
            if (c.GetType() == type && c.GetType().GetMethod("Clear") != null)
                    c.GetType().InvokeMember("Clear", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, c, null);
    }
Saeed Bolhasani
  • 552
  • 3
  • 15
0

What about using generics instead?

public void ClearControlsOfType<T>(ControlCollection controls) where T : IClearable
    foreach(var control in controls.OfType<T>()) {
        control.Clear();
    }
}

where IClearable could be anything that has a Clear method; you don't need a specific interface for this if you already have a class that ensures this, but you need something to ensure it at compile time, otherwise you need to use reflection.

George Helyar
  • 4,319
  • 1
  • 22
  • 20
0

Try this one

    public static void ControlClear<type>(Control.ControlCollection controls) where type : Control
    {
        foreach (Control c in controls)
            if (c is type)
                ((type)c).Text = "";
    }

//===============

   ControlClear<TextBox>(Controls);
mrbm
  • 1,136
  • 1
  • 12
  • 36