Jack
Jack

Reputation: 16724

Get control by name, including children

I'm trying to get a control by name. I wrote the following code:

public Control GetControlByName(string name)
{
    Control currentControl; 

    for(int i = 0,count = Controls.Count; i < count; i++)
    {
        currentControl = Controls[i];

        if (currentControl.HasChildren)
        {
            while (currentControl.HasChildren)
            {
                for(int x = 0,size = currentControl.Controls.Count; x < size; x++)
                {
                    currentControl = currentControl.Controls[x];

                    if (currentControl.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                    {
                        return currentControl;
                    }
                }
            }
        }
        else
        {
            if (currentControl.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
            {
                return currentControl;
            }
        }
    }

    return null;
}

It only ever returns null. Can someone point out my mistake? Any help or ways to improve this code are welcomed.

Upvotes: 4

Views: 10545

Answers (3)

glenn223
glenn223

Reputation: 303

A slight tweak for if you're not using System.Windows.Forms (this is what .Find(string, bool) works off too)

public static class MyExensions
{
    public static Control FindControlRecursively(this Control control, string name)
    {
        Control result = null;

        if (control.ID.Equals(name))
        {
            result = control;
        }
        else
        {
            for (var i = 0; i < control.Controls.Count; i++)
            {
                result = control.Controls[i].FindControlRecursively(name);

                if (result != null)
                {
                    break;
                }
            }
        }

        return result;
    }

    public static T FindControlRecursively<T>(this Control control, string name)
        where T : Control
    {
        return control.FindControlRecursively(name) as T;
    }
}

p.s. Yes I know it's an old question, but in case it helps 😁

Upvotes: 1

Jim D&#39;Angelo
Jim D&#39;Angelo

Reputation: 3952

I actually wrote some extension methods at work to do just this thing:

public static class MyExensions ()
{
    public static Control FindControlRecursively (this Control control, string name)
    {
        Control result = null;

        if (control.ID.Equals (name))
        {
            result = control;
        }
        else
        {
            foreach (var child in control.Children)
            {
                result = child.FindControlRecursively (name);

                if (result != null)
                {
                    break;
                }
            }
        }

        return result;
    }

    public static T FindControlRecursively<T> (this Control control, string name)
        where T: Control
    {
        return control.FindControlRecursively (name) as T;
    }
}

Note: Null checks removed for the sake of simplicity.

You can use it to find, say, a TextBox on your form like so:

public class MyForm : Form
{
    public void SetSomeText ()
    {
        var control = this.FindControlRecursively<TextBox> ("myTextboxName");

        if (control != null)
        {
            control.Text = "I found it!";
        }

        // Or...

        var control2 = this.FindControlRecursively ("myTextboxName2") as TextBox;

        if (control != null)
        {
            control2.Text = "I found this one, also!";
        }
    }
}

Edit

Of course, this is a depth-first algorithm, which might be slow depending on how deep your control chain is. You might rewrite it to use a breadth-first algorithm if you see that it is too slow.

Upvotes: 1

competent_tech
competent_tech

Reputation: 44971

Just use the Controls collection Find method:

            var aoControls = this.Controls.Find("MyControlName", true);
            if ((aoControls != null) && (aoControls.Length != 0))
            {
                Control foundControl = aoControls[0];
            }

Upvotes: 13

Related Questions