Find Controls nested inside Repeater Control

2019-02-23 18:38发布

I'm trying to find the values of TextBoxes which are rendered in a Repeater though a UserControl, i.e. the Repeater has a Placeholder for the UserControl, and inside the UserControl is where the TextBox markup actually exists. I've done this before with TextBoxes directly inside of a Repeater before, which was fairly straight forward, and I'm wondering why this apparently can't be accomplished the same way. Here is the Default page with the Repeater, which contains a Placeholder...

 <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<form class="formee">
    <fieldset>
         <legend>Faculty Information</legend>
         <div class="grid-4-12">
             <asp:Label ID="lblFirstName1" runat="server" Text="First Name"></asp:Label>
             <asp:Label ID="lblFirstName2" runat="server" Text="" ></asp:Label>
             <asp:Label ID ="lblSalary" runat="server" Text="" ClientIDMode="Static"></asp:Label>
        </div>
        <div class="grid-6-12">
            <asp:Label ID="lblLastName1" runat="server" Text="Last Name"></asp:Label>
            <asp:Label ID="lblLastName2" runat="server" Text=""></asp:Label>
        </div>
    </fieldset>
</form>
<div id="repeaterDiv">
    <asp:Repeater ID="rptBudget" runat="server" ClientIDMode="Static">
        <ItemTemplate>
                <asp:PlaceHolder ID="phBudget" runat="server" EnableViewState="true" />
                    <br />
        </ItemTemplate>
    </asp:Repeater>

    <asp:Button ID="btnAddBudgetControl" runat="server" Text="Add"
                CausesValidation="false" OnClick="AddBudgetControl" CssClass="addBudgetControl"/>
    <asp:Button ID="btnDisplayEntries" runat="server" Text="Display Entries" CausesValidation="false" OnClick="DisplayEntries" />
</div>
<div>
    <asp:TextBox ID="txtTotalPercent" runat="server"  ClientIDMode="Static"></asp:TextBox>
    <asp:TextBox ID="txtGrandTotal" runat="server" ClientIDMode="Static"></asp:TextBox>
    <asp:Label ID="lblCtrls" runat="server" Text=""></asp:Label>
</div>

...and the UserControl which is inserted in the place of the Placeholder...

 <fieldset>
        <legend>Faculty Salary Form</legend>
        <table cellspacing="10" id="values">
            <tr>
                <td>
                    <asp:Label ID="lblServiceType" runat="server" Text="Service"></asp:Label>
                    <asp:DropDownList runat="server" ID="ddlServiceType" CssClass="serviceType" />
                </td>
                <td>
                    <asp:Label ID="lblSpeedCode" runat="server" Text="Speed Code"></asp:Label>
                    <asp:DropDownList runat="server" ID="ddlSpeedCode" CssClass="speedType" />
                </td>
                <td>
                    <asp:Label ID="lblPercentage" runat="server" Text="Percentage"></asp:Label>
                    <asp:Textbox ID="txtPercentage" runat="server" CssClass="percentCommitment" ClientIDMode="Static" EnableViewState="true" />
                </td>
                <td>
                    <asp:Label ID="lblTotal" runat="server" Text="Total"></asp:Label>
                    <asp:TextBox ID="txtTotal" runat="server" CssClass="amountCommitment" ClientIDMode="Static"  EnableViewState="true"/>
                </td>
                <td>
                    <asp:Button ID="btnRemove" runat="server" Text="Remove Item" OnClick="RemoveItem" ClientIDMode="Static" CssClass="btnRemove" />
                </td>
            </tr>
            <tr>
            </tr>
        </table>
    </fieldset>

...but when the following code runs for the Display button's OnClick, I always get a null value for any and all TextBoxes (and DropDowns) in the UserControl...

protected void DisplayEntries(object sender, EventArgs e)
{
    foreach (RepeaterItem repeated in rptBudget.Items)
    {
        TextBox txtPercentage = (TextBox)repeated.FindControl("txtPercentage");
        if (txtPercentage == null)
        {
            lblCtrls.Text += " null; ";
        }
        else
        {
            lblCtrls.Text += txtPercentage.Text + "; ";
        }
    }
}

What's the best way to access these values? Thanks.

3条回答
唯我独甜
2楼-- · 2019-02-23 19:01

Try loading the placeholder first and then looking for the textboxes in the placeholder:

Something like this:

pseudo

var ph = repeated.FindControl("phBudget");
var txtBox = ph.FindControl("txtPercentage");

/pseudo

查看更多
仙女界的扛把子
3楼-- · 2019-02-23 19:14

txtPercentage Textbox is located inside Usercontrol, so use the following helper method to retrieve it.

Helper Method

public static Control FindControlRecursive(Control root, string id)
{
   if (root.ID == id) 
     return root;

   return root.Controls.Cast<Control>()
      .Select(c => FindControlRecursive(c, id))
      .FirstOrDefault(c => c != null);
}

Usage

foreach (RepeaterItem repeated in rptBudget.Items)
{
   TextBox txtPercentage =            
      (TextBox)FindControlRecursive(repeated, "txtPercentage");  
   ...   
}
查看更多
时光不老,我们不散
4楼-- · 2019-02-23 19:14

You need to first get the UserControl, then use FindControl on the UC itself.

查看更多
登录 后发表回答