在webform中查找控件

时间:2009-03-06 16:28:06

标签: c# asp.net webforms

我有一个Web内容表单,需要访问内容面板中的控件。我知道有两种访问控件的方法:

  1. TextBox txt = (TextBox)Page.Controls[0].Controls[3].Controls[48].Controls[6]
  2. 编写一个搜索所有控件的递归函数。
  3. 还有其他更简单的方法,因为Page.FindControl在这种情况下不起作用。 我问的原因是我感觉像Page对象或Content Panel对象应该有一个方法来查找子控件,但找不到类似的东西。

2 个答案:

答案 0 :(得分:26)

问题是FindControl()不会遍历某些控制子项,例如模板化控件。如果您使用的控件存在于模板中,则无法找到它。

所以我们添加了以下扩展方法来处理这个问题。如果您没有使用3.5或想要避免使用扩展方法,则可以使用这些方法创建通用库。

您现在可以通过编码获得您所追求的控制权:

var button = Page.GetControl("MyButton") as Button;

扩展方法为您执行递归工作。希望这有帮助!

public static IEnumerable<Control> Flatten(this ControlCollection controls)
{
    List<Control> list = new List<Control>();
    controls.Traverse(c => list.Add(c));
    return list;
}

public static IEnumerable<Control> Flatten(this ControlCollection controls,     
    Func<Control, bool> predicate)
{
    List<Control> list = new List<Control>();
    controls.Traverse(c => { if (predicate(c)) list.Add(c); });
    return list;
}

public static void Traverse(this ControlCollection controls, Action<Control> action)
{
    foreach (Control control in controls)
    {
        action(control);
        if (control.HasControls())
        {
            control.Controls.Traverse(action);
        }
    }
}

public static Control GetControl(this Control control, string id)
{
    return control.Controls.Flatten(c => c.ID == id).SingleOrDefault();
}

public static IEnumerable<Control> GetControls(this Control control)
{
    return control.Controls.Flatten();
}

答案 1 :(得分:1)

我想将您的GetControls功能更改为通用功能,如下所示:

public static T GetControl<T>(this Control control, string id) where T:Control
{
    var result = control.Controls.Flatten(c => (c.GetType().IsSubclassOf(typeof(T))) && (c.ID == id)).SingleOrDefault();
    if (result == null)
        return null;
    return result as T;
}

然后,

public static Control GetControl(this Control control, string id)
{
    return control.GetControl<Control>(id);
}

这样,调用者会调用类似的东西:

var button = Page.GetControl<Button>("MyButton");