Looping through children controls inside Updatepan

2019-07-27 17:41发布

I have written a method that loops through all the properties of an object and maps them to controls that have the same name (or prefix + name). The issue is that I have certain controls inside an update panel (drop down lists that change when a different option is selected) that are not being found when running through this method. I read this and adapted the method below to accommodate for that, but it still will not find the controls inside the update panel. All the controls have IDs and runat="server".

public static void MapObjectToPage(this object obj, Control parent, string prefix = "")
{
    Type type = obj.GetType();
    Dictionary<string, PropertyInfo> props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(info => prefix + info.Name.ToLower());

    ControlCollection theControls = parent is UpdatePanel ? ((UpdatePanel)parent).ContentTemplateContainer.Controls : parent.Controls;

    foreach (Control c in theControls)
    {
        if (props.Keys.Contains(c.ClientID.ToLower()) && props[c.ClientID.ToLower()].GetValue(obj, null) != null)
        {
            string key = c.ClientID.ToLower();
            if (c.GetType() == typeof(TextBox))
            {
                ((TextBox)c).Text = props[key].PropertyType == typeof(DateTime?)
                    || props[key].PropertyType == typeof(DateTime)
                    ? ((DateTime)props[key].GetValue(obj, null)).ToShortDateString()
                    : props[key].GetValue(obj, null).ToString();
            }
            else if (c.GetType() == typeof(HtmlInputText))
            {
                ((HtmlInputText)c).Value = props[key].PropertyType == typeof(DateTime?)
                    || props[key].PropertyType == typeof(DateTime)
                    ? ((DateTime)props[key].GetValue(obj, null)).ToShortDateString()
                    : props[key].GetValue(obj, null).ToString();
            }
            //snip!
        }
        if (c is UpdatePanel
        ? ((UpdatePanel)c).ContentTemplateContainer.HasControls()
        : c.HasControls())
        {
            obj.MapObjectToPage(c);
        }
    }
}

2条回答
何必那么认真
2楼-- · 2019-07-27 17:52

Try to add this two methods to a new or existing class:

    public static List<Control> FlattenChildren(this Control control)
    {
        var children = control.Controls.Cast<Control>();
        return children.SelectMany(c => FlattenChildren(c).Where(a => a is Label || a is Literal || a is Button || a is ImageButton || a is GridView || a is HyperLink || a is TabContainer || a is DropDownList || a is Panel)).Concat(children).ToList();
    }
    public static List<Control> GetAllControls(Control control)
    {
        var children = control.Controls.Cast<Control>();
        return children.SelectMany(c => FlattenChildren(c)).Concat(children).ToList();
    }

You can call the GetAllControls method with the updatePanel as parameter (or the main container). The method returns all the children of the 'control' parameter. Also, you can remove the Where clause to retrieve all the controls (not those of a certain type).

I hope this will help you!

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-07-27 17:53

UpdatePanel is directly access. You don't need to/can't use FindControl to find it. Use this

foreach (Control ctrl in YourUpdatepanelID.ContentTemplateContainer.Controls)
{
    if (ctrl.GetType() == typeof(TextBox))
        ((TextBox)(ctrl)).Text = string.Empty;
    if (ctrl.GetType() == typeof(CheckBox))
        ((CheckBox)(ctrl)).Checked = false;
} 
查看更多
登录 后发表回答