TheGateKeeper TheGateKeeper - 2 months ago 8
ASP.NET (C#) Question

Getting a lits of all child controls of a control, by type

im trying to make a method that creates a List with the name of all the child controls of a DetalsView that are of type string.

The closest i got was:

foreach (Control c in dv.Controls)
{
if (c is Label)
{
controlsToCheck.Add(c.ID);
}
}

foreach (string s in controlsToCheck)
{
Label lbl = (Label)dv.FindControl(s);
if (lbl.Text == "")
{
lbl.Text = "None";
lbl.CssClass = "bold";
}
}


However, all this does is iterate once in the first foreach, and then exit (ie. dv.Controls only returns one item). If i use FindControl, i can get to the items, but it means i have to do it for each item.

Any toughts?

Thanks!

Edit: here is my DetailsView (i cut some things out, which where just more controls so it fits on the page):

<asp:DetailsView DefaultMode="ReadOnly" FieldHeaderStyle-CssClass="dwHeader" CssClass="marginLeftRightBottom10px"
AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" GridLines="None"
ID="dvIndividualItem" runat="server" AutoGenerateRows="False" DataSourceID="sqldsSingleItem"
OnDataBound="dvIndividualItem_DataBound">
<Fields>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Item Name:</h1>
<p>
The name of the item.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat="server" ID="lblItemName" Text='<%# Bind("itemName") %>'></asp:Label>
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox runat="server" ID="tbItemName"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Item Description:</h1>
<p>
The description of the item.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat="server" ID="lblItemDescription" Text='<%# Bind("itemDescription") %>'></asp:Label>
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox runat="server" ID="tbItemDescription"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Item Image:</h1>
<p>
The image of the item.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:Image runat="server" ID="imgItem" Width="40px" Height="40px" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox ReadOnly="true" runat="server" ID="tbItemImage"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Item Type:</h1>
<p>
Specifies the item type.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblItemType" Text='<%# Eval("itemType") %>' runat="server" />
</ItemTemplate>
<%-- <InsertItemTemplate>
<asp:DropDownList AutoPostBack="true" OnSelectedIndexChanged="ddlItemTypes_SelectedIndexChanged"
DataTextField="itemType" DataValueField="typeId" DataSourceID="sqldsTier1Category"
ID="ddlItemTypes" runat="server">
</asp:DropDownList>
<asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:myDbConnection%>" ID="sqldsTier1Category"
runat="server" SelectCommand="dbo.getItemCategories" SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
</InsertItemTemplate>--%>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Item SubType:</h1>
<p>
Specifies the sub-item type.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblSubItemType" Text='<%# Eval("itemSubType") %>' runat="server" />
</ItemTemplate>
<%-- <InsertItemTemplate>
<asp:DropDownList OnDataBound="ddlItemSubTypes_OnDataBound" AutoPostBack="true" DataTextField="itemSubType"
DataValueField="subTypeId" DataSourceID="sqldsTier2Category" ID="ddlItemSubTypes"
runat="server">
</asp:DropDownList>
<asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:myDbConnection%>" ID="sqldsTier2Category"
runat="server" SelectCommand="dbo.getItemSubCategories" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter ControlID="dwNewItem$ddlItemTypes" Name="typeId" PropertyName="SelectedValue"
DbType="Int16" />
</SelectParameters>
</asp:SqlDataSource>
</InsertItemTemplate>--%>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Item SubSubType:</h1>
<p>
Specifies the sub-sub-item type.</p>
<p>
<i>Not always applicable.</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblSubSubItemType" Text='<%# Eval("itemSubSubType") %>' runat="server" />
</ItemTemplate>
<%-- <InsertItemTemplate>
<asp:DropDownList DataTextField="itemSubSubType" DataValueField="subSubTypeId" DataSourceID="sqldsTier3Category"
ID="ddlItemSubSubTypes" runat="server">
</asp:DropDownList>
<asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:myDbConnection%>" ID="sqldsTier3Category"
runat="server" SelectCommand="dbo.getItemSubSubCategories" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter ControlID="dwNewItem$ddlItemSubTypes" Name="subTypeId" PropertyName="SelectedValue"
DbType="Int16" />
</SelectParameters>
</asp:SqlDataSource>
</InsertItemTemplate>--%>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Requires Sword Swinger Class?</h1>
<p>
Specifies whether the item can only be used by the Sword Swinger.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="cbReqSwordSwinger" Text='<%# Bind("requiresSwordSwinger") %>' runat="server" />
</ItemTemplate>
<%-- <InsertItemTemplate>
<asp:CheckBox runat="server" ID="cbReqSwordSwinder" />
</InsertItemTemplate>--%>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Requires Rat Catcher Class?</h1>
<p>
Specifies whether the item can only be used by the Rat Catcher.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="cbReqRatCatcher" Text='<%# Bind("requiresRatCatcher") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:CheckBox runat="server" ID="cbReqRatCatcher" />
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<h1>
Requires Spell Mumbler Class?</h1>
<p>
Specifies whether the item can only be used by the Spell Mumbler.</p>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="cbReqSpellMumbler" Text='<%# Bind("requiresSpellMumbler") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:CheckBox runat="server" ID="cbReqSpellMumbler" />
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="colorBlue dwHeader">
<HeaderTemplate>
<h1>
Strength permanently added:</h1>
<p>
Specifies the amount of strength the item permanently adds to your character.</p>
<p>
<i>Only available when the item is set to type "Consumable"</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblPermanentStrength" Text='<%# Bind("permanentStrength") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox Enabled="false" runat="server" ID="tbItemPermanentStr"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="colorBlue dwHeader">
<HeaderTemplate>
<h1>
Agility permanently added:</h1>
<p>
Specifies the amount of agility the item permanently adds to your character.</p>
<p>
<i>Only available when the item is set to type "Consumable"</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblPermanentAgility" Text='<%# Bind("permanentAgility") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox Enabled="false" runat="server" ID="tbItemPermanentAgl"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="colorBlue dwHeader">
<HeaderTemplate>
<h1>
Magical Power permanently added:</h1>
<p>
Specifies the amount of magical power the item permanently adds to your character.</p>
<p>
<i>Only available when the item is set to type "Consumable"</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblPermanentMagicalPower" Text='<%# Bind("permanentMagicalPower") %>'
runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox Enabled="false" runat="server" ID="tbItemPermanentMP"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="colorBlue dwHeader">
<HeaderTemplate>
<h1>
Health Points restored:</h1>
<p>
Specifies the amount of health points the item restores.</p>
<p>
<i>Only available when the item is set to type "Consumable"</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblHPRestored" Text='<%# Bind("restoresHealthPoints") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox Enabled="false" runat="server" ID="tbItemRestoresHp"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="colorBlue dwHeader">
<HeaderTemplate>
<h1>
Mana Points restored:</h1>
<p>
Specifies the amount of mana points the item restores.</p>
<p>
<i>Only available when the item is set to type "Consumable"</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblManaRestored" Text='<%# Bind("restoresMana") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox Enabled="false" runat="server" ID="tbItemRestoresMana"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="colorBlue dwHeader">
<HeaderTemplate>
<h1>
Health Points permanently added:</h1>
<p>
Specifies the amount of health points the item permanently adds to your character.</p>
<p>
<i>Only available when the item is set to type "Consumable"</i></p>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblPermanentHP" Text='<%# Bind("permanentHealth") %>' runat="server" />
</ItemTemplate>
<InsertItemTemplate>
<asp:TextBox Enabled="false" runat="server" ID="tbItemPermanentHP"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>

Answer

Try this

    public static IEnumerable<Control> GetAllControls(Control parent)
    {
        foreach (Control control in parent.Controls)
        {
            yield return control;
            foreach (Control descendant in GetAllControls(control))
            {
                yield return descendant;
            }
        }
    }

and call

List<Control> ControlsToCheck = GetAllControls(dv).OfType<Label>().ToList();