在webform中找到控件

时间:2022-11-24 12:06:28

I have a Web content form and need to access a control inside the content panel. I know of two ways to access the control:

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

  1. TextBox txt = (TextBox)Page.Controls[0].Controls[3].Controls[48].Controls[6]
  2. 文本框txt =(文本框)Page.Controls[0].合肥[3].合肥[48].合肥[6]
  3. By writing a recursive function that searches through all controls.
  4. 通过编写一个递归函数来搜索所有控件。

Is there any other easier way, since Page.FindControl doesn’t work in this instance. The reason I am asking is it feels to me like the Page object or the Content Panel object should have a method to find a child control, but can’t find anything like it.

还有其他更简单的方法吗?FindControl在这个实例中不起作用。我之所以问这个问题,是因为我觉得Page对象或Content Panel对象应该有一个方法来查找子控件,但找不到类似的东西。

2 个解决方案

#1


26  

The issue is that FindControl() does not traverse certain control children such as a templated control. If the control you are after lives in a template, it won't be found.

问题是FindControl()没有遍历某些控件子元素,比如模板控件。如果你的控制住在模板中,它就找不到。

So we added the following extension methods to deal with this. If you are not using 3.5 or want to avoid the extension methods, you could make a general purpose library out of these.

我们添加了以下扩展方法来处理这个问题。如果您不使用3.5或希望避免使用扩展方法,您可以使用这些方法创建一个通用库。

You can now get the control you are after by coding:

你现在可以通过编码得到你想要的控制:

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

The extension methods do the recursive work for you. Hope this helps!

扩展方法为您做递归工作。希望这可以帮助!

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

#2


0  

I would like to change your GetControls function to a generic one as follows:

我想将您的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;
}

And Then,

然后,

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

This way, the caller would call something like:

这样,打电话的人会这样打电话:

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

#1


26  

The issue is that FindControl() does not traverse certain control children such as a templated control. If the control you are after lives in a template, it won't be found.

问题是FindControl()没有遍历某些控件子元素,比如模板控件。如果你的控制住在模板中,它就找不到。

So we added the following extension methods to deal with this. If you are not using 3.5 or want to avoid the extension methods, you could make a general purpose library out of these.

我们添加了以下扩展方法来处理这个问题。如果您不使用3.5或希望避免使用扩展方法,您可以使用这些方法创建一个通用库。

You can now get the control you are after by coding:

你现在可以通过编码得到你想要的控制:

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

The extension methods do the recursive work for you. Hope this helps!

扩展方法为您做递归工作。希望这可以帮助!

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

#2


0  

I would like to change your GetControls function to a generic one as follows:

我想将您的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;
}

And Then,

然后,

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

This way, the caller would call something like:

这样,打电话的人会这样打电话:

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