Luana
Luana

Reputation: 183

Listing Components (not controls)

My code displayed below shows all the visual and non-visual components of a form (OpenDialogs, SaveDialogs, etc). I wish I could specify the component name (no control) rather than knowing all the form elements, something like this:

private IEnumerable <Component> EnumerateComponents ()
{
    return this.GetType () GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
    .Where (F => typeof (Component) .IsAssignableFrom (f.FieldType))
    .Where (F => typeof (Control) .IsAssignableFrom (f.FieldType))
    //.Where  componentName.thatIinformed == "OpenDialog1" <<<<<======
    .Select (F => f.GetValue (this))
    .OfType <Component> ();
}

Is it possible ?

Upvotes: 0

Views: 52

Answers (1)

Anthony
Anthony

Reputation: 9571

It looks like you want something more along the lines of this:

public IEnumerable<Component> EnumerateComponents()
{
    return this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(x => typeof(Component).IsAssignableFrom(x.PropertyType))
        .Select(x => x.GetValue(this)).Cast<Component>();
}

I tried this with the following custom UserControl:

public sealed class MyCustomControl : UserControl
{
    // Adding some Controls for testing
    public Label MyLabel1 { get; set; }
    public Label MyLabel2 { get; set; }

    // Adding a Component (not a Control) for testing
    public System.Windows.Forms.Timer MyTimer1 { get; set; }

    public IEnumerable<Component> EnumerateComponents()
    {
        return this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(x => typeof(Component).IsAssignableFrom(x.PropertyType))
            .Select(x => x.GetValue(this)).Cast<Component>();
    }

    public IEnumerable<PropertyInfo> EnumerateProperties()
    {

        return this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(x => typeof(Component).IsAssignableFrom(x.PropertyType));
    }
}

The EnumerateProperties method was just so I could test that it was picking up the properties I wanted. It included the 2 Label properties I added as well as the Timer property I included (because it isn't a Control, just a Component). It also picked up 6 other properties which it inherits from the UserControl which meet the criteria: ActiveControl, ParentForm, ContextMenu, ContextMenuStrip, Parent, and TopLevelControl.

Now, getting the values for each one of these is likely to return a lot of null values, so you may also need to filter out non-null values. Using OfType instead of Cast also has the side effect of removing null values.

Upvotes: 1

Related Questions