4

In my code I need to loop through the controls in a GroupBox and process the control only if it a ComboBox. I am using the code:

foreach (System.Windows.Forms.Control grpbxChild in this.gpbx.Controls)
{
    if (grpbxChild.GetType().Name.Trim() == "ComboBox")
    {
        // Process here
    }
}

My question is: Instead of looping through all the controls and processing only the combo boxes is is possible to get only the combo boxes from the GroupBox? Something like this:

foreach (System.Windows.Forms.Control grpbxChild in this.gpbx.Controls.GetControlsOfType(ComboBox))
{
    // Process here
}
Rashmi Pandit
  • 23,230
  • 17
  • 71
  • 111

5 Answers5

8

Since you are using C# 2.0, you're pretty much out of luck. You could write a function yourself. In C# 3.0 you'd just do:

foreach (var control in groupBox.Controls.OfType<ComboBox>())
{
    // ...
}

C# 2.0 solution:

public static IEnumerable<T> GetControlsOfType<T>(ControlCollection controls)
    where T : Control
{
    foreach(Control c in controls)
        if (c is T)
            yield return (T)c;
}

which you'd use like:

foreach (ComboBox c in GetControlsOfType<ComboBox>(groupBox.Controls))
{
    // ...
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • +1 for mentioning the OfType syntax, but the presented "pseudosolution" still requires a loop through all the child controls. Which doesn't address the basic problem. – Cerebrus May 15 '09 at 09:44
  • @Cerebrus: It doesn't require a loop if you don't need to do anything with it. If you just want the collection of ComboBoxes you could just do: List list = new List(GetControlsOfType(groupBox.Controls)); – Mehrdad Afshari May 15 '09 at 09:46
  • Thanks Mehrdad... this works!!! Don't call it pseudosolution. It is the solution. You were just short of the where clause. Please edit the response to add it: public static IEnumerable GetControlsOfType(Control.ControlCollection controls) where T : Control – Rashmi Pandit May 15 '09 at 10:38
  • Oh yep, you're right. It's required since you're doing the cast. I didn't notice that. – Mehrdad Afshari May 15 '09 at 11:03
2

Mehrdad is quite right, but your syntax (even if you are using C# 2.0) is overly complicated.

I find this to be simpler :

foreach (Control c in gpBx.Controls) 
{ 
  if (c is ComboBox) 
  { 
    // Do something.
  }
}
Cerebrus
  • 25,615
  • 8
  • 56
  • 70
  • Wrong. typeof(c) is always `System.Type` so `typeof(c) is ComboBox` is always false. You should do `c is ComboBox` – Mehrdad Afshari May 15 '09 at 09:44
  • Ahh, right! My mistake. Have edited my post with the correction. – Cerebrus May 15 '09 at 09:50
  • Yeah. It's correct now. For the sake of completeness, typeof(c) will fail to compile in C# if `c` is not a type. That is, you can't do typeof on a variable at all. – Mehrdad Afshari May 15 '09 at 09:52
  • Yes, I was about to inform you that it will not compile because the typeof keyword evaluates the built-in System.Type, not the runtime type. Thanks for the correction! – Cerebrus May 15 '09 at 09:55
  • I am using GetType().Name because I have a switch case. c is ComboBox is definitely better way of comparing datatype. Thanks – Rashmi Pandit May 15 '09 at 10:13
  • @Rashmi Pandit: Indeed, I'd suggest rewriting your switch case with a set of `if` statements using `is` or `as` operators. It's the right way of doing it. What you are doing is relying on the name of type instead of the actual type itself. And btw, it might have inferior performance. – Mehrdad Afshari May 15 '09 at 10:24
0
foreach (Control items in this.Controls.OfType<GroupBox>())
{
    foreach (ComboBox item in items.Controls.OfType<ComboBox>())
    {
        // your processing goes here
    }
}
Sergey Glotov
  • 20,200
  • 11
  • 84
  • 98
Sajjad
  • 11
0
if (!(grpbxChild is System.Windows.Forms.Combobox)) continue;

// do your processing goes here
grpbxChild.Text += " is GroupBox child";
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Chris Richner
  • 2,863
  • 2
  • 26
  • 38
  • 1
    This will *not* compile. The precedence of `is` is lower than `!`. As a result, the compiler will first try to apply `!` to GroupBox variable which fails. For more info: http://stackoverflow.com/questions/811614/c-is-keyword-and-checking-for-not – Mehrdad Afshari May 15 '09 at 10:10
  • yes, you're right with that, my fault should be if (!(grpbxChild is System.Windows.Forms.Combobox)) – Chris Richner May 15 '09 at 14:05
0
foreach (System.Windows.Forms.Control grpbxChild in this.gpbx.Controls)
{
    if (grpbxChild is ComboBox)
    {
        // Process here
    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433