2011-09-26 50 views
2

得到一個控件的所有子控件的一個l試圖創建一個方法,該方法創建一個帶有類型爲字符串的DetalsView的所有子控件的名稱的List。通過類型

我得到的最接近是:

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

然而,這一切都在第一的foreach循環一次,然後退出(即dv.Controls只返回一個項目)。如果我使用FindControl,我可以到達項目,但這意味着我必須爲每個項目執行此操作。

有沒有粘性?

謝謝!

編輯:這裏是我的DetailsView控件(我削減了一些東西出來,所以它適合在網頁上哪裏只是更多的控制):

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

回答

7

試試這個

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

,並呼籲

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

嗯...你聽起來有點太複雜了。以前從未使用過這些關鍵字。你能解釋爲什麼我的工作不好嗎? – TheGateKeeper

+0

@TheGateKeeper DetailsView中的控件不只在一個級別。它們是嵌套的。要獲得所有控件,您必須使用遞歸函數,直到獲得沒有任何更多子控件的簡單控件。 –

+0

好的,我明白了。你的方法是否僅迭代2個級別? – TheGateKeeper

1

當您通過dv.Controls迭代時,它僅顯示第一級控件unde在你的DetalsView之下。如果需要查找所有標籤,則需要遍歷所有子控件,然後遍歷子項等。

@Bala R.的答案就是一個很好的例子。你也可以在this answer上找到一些例子。

+0

嗯,所以如果我直接添加一個控件到它的模板,wouldnt被直接包含的detailsView?請解釋 啊等待,我想我明白了,它是因爲Div標籤算作控件吧?所以你也需要重複這些。 – TheGateKeeper

+0

@TheGateKeeper號一個DetailsView創建一個Table控件,然後包含一系列行,這些行將包含表格單元格,然後最終包含您正在查找的控件。這就是爲什麼如果你想循環它內部的控件,你需要遞歸的。 –

1

我修改巴拉的r解了一點。我做到了,只有yeilds你有興趣,所以你並不需要調用.OfType<T>作爲第二步控制的類型的通用擴展方法:

public static IEnumerable<T> GetControls<T>(this Control parent) where T : Control 
{ 
    foreach (Control control in parent.Controls) 
    { 
     if (control is T) yield return control as T; 
     foreach (Control descendant in GetControls<T>(control)) 
     { 
      if (control is T) 
       yield return descendant as T; 
     } 
    } 
} 

像這樣來使用:

List<Label> labels = dv.GetControls<Label>().ToList(); 

foreach(Label label in dv.GetControls<Label>()) 
{ 
    //do stuff 
} 
+0

這很好。 – bgx