views:

1269

answers:

5

Hi, 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
}
+6  A: 

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))
{
    // ...
}
Mehrdad Afshari
+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
@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<ComboBox> list = new List<ComboBox>(GetControlsOfType<ComboBox>(groupBox.Controls));
Mehrdad Afshari
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<T> GetControlsOfType<T>(Control.ControlCollection controls) where T : Control
Rashmi Pandit
Oh yep, you're right. It's required since you're doing the cast. I didn't notice that.
Mehrdad Afshari
A: 
if (!(grpbxChild is System.Windows.Forms.Combobox)) continue;

// do your processing goes here
grpbxChild.Text += " is GroupBox child";
Chris Richner
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
yes, you're right with that, my faultshould be if (!(grpbxChild is System.Windows.Forms.Combobox))
Chris Richner
+2  A: 

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
Wrong. typeof(c) is always `System.Type` so `typeof(c) is ComboBox` is always false. You should do `c is ComboBox`
Mehrdad Afshari
Ahh, right! My mistake. Have edited my post with the correction.
Cerebrus
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
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
I am using GetType().Name because I have a switch case. c is ComboBox is definitely better way of comparing datatype. Thanks
Rashmi Pandit
@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
@Rashmi: You're welcome, but where's my vote?! :P
Cerebrus
A: 
foreach (System.Windows.Forms.Control grpbxChild in this.gpbx.Controls)
{
    if (grpbxChild is ComboBox)
    {
        // Process here
    }
}
A: 

No Answer, just a thank you. This helped me resolve an issue I was fighting with, while using dynamically created radio buttons.

Richard