【问题标题】:Get control by name, including children通过名字获得控制权,包括孩子
【发布时间】:2012-02-02 22:59:32
【问题描述】:

我正在尝试按名称获取控件。我写了以下代码:

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;
}

它只返回空值。有人可以指出我的错误吗?欢迎任何帮助或改进此代码的方法。

【问题讨论】:

标签: c# .net winforms controls


【解决方案1】:

只需使用 Controls 集合Find 方法:

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

【讨论】:

  • 这是递归的吗?它会找到孩子的孩子吗?
  • @User:是的,Find 的第二个参数就是这样。
【解决方案2】:

我实际上在工作中写了一些扩展方法来做这件事:

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;
    }
}

注意:为简单起见删除了空检查。

您可以使用它在表单上查找TextBox,如下所示:

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!";
        }
    }
}

编辑

当然,这是一个深度优先算法,它可能会很慢,具体取决于您的控制链有多深。如果您发现它太慢,您可以重写它以使用 广度优先 算法。

【讨论】:

    【解决方案3】:

    如果您使用System.Windows.Forms,请稍作调整(这也是.Find(string, bool) 的工作原理)

    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;
        }
    }
    

    附言是的,我知道这是一个老问题,但万一它有帮助?

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 2011-07-25
      • 2016-02-29
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2023-03-11
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多