Search code examples
c#asp.netasp.net-4.5

Establish A Reference To A DropDownList Within A Repeater In asp.net 4.5


In the following code I don’t understand why I can’t establish a reference to the dropdownlist (ddRoles) in the repeater:

            <asp:Repeater ItemType="HR_Test_v0_1.Pages.Admin.UserDetails"
                 ID="repeaterManage" 
                 SelectMethod="GetUsers" runat="server">
                <ItemTemplate>
                    <tr>
                        <td><%# Item.Name %></td>
                        <td>
                            <%# Item.Roles %>
                            <asp:DropDownList ID="ddRoles" 
                                name="ddRoles"
                                runat="server"
                                AppendDataBoundItems="true"
                                SelectMethod="GetRoles" 
                                SelectedValue="<%# Item.Roles %>"
                                AutoPostBack="true"
                                />
                        </td>
                        <td><%# Item.Locked %></td>
                        <td><%# Item.Online %></td>
                        <td><button type="submit" name="unlock"
                            value="<%# Item.Name %>">Unlock</button></td>
                        <td><button type="submit" name="delete"
                            value="<%# Item.Name %>">Delete</button></td>
                    </tr>
                </ItemTemplate>
            </asp:Repeater>

Code behind:

    protected void Page_Load(object sender, EventArgs e)
    {
        if(IsPostBack)
        {

            DropDownList ddlist = (DropDownList) RepeaterManage
                      .FindControl("repeaterManage$ddRoles");

            Debug.Print(ddlist.UniqueID);

        }
    }

When I select a different item in the roles ddRoles drop down list, how do I get the new value that the user has selected?

EDIT:

I can now set a reference to the dropdown box in the code below:

    private DropDownList ddListControl;

    protected void repeaterManage_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        ddListControl = e.Item.FindControl("ddRoles") as DropDownList;
        Debug.Print(string.Format("New value: {0}", ddListControl.ID));

    }

This gets a reference, but doesn't give me the value that the user has supplied. What I really want to do is detect the change in the value of the dropdownlist in the Page_Load event and then do something in response to the change.

Additional code:

    public IEnumerable<UserDetails>GetUsers()
    {
        return Membership.GetAllUsers()
            .Cast<MembershipUser>().Select(m => new UserDetails
            {
                Name = m.UserName,
                Roles = string.Join(",", Roles.GetRolesForUser(m.UserName)),
                Locked = m.IsLockedOut,
                Online = m.IsOnline
            });
    }

    public IEnumerable<string>GetRoles()
    {
        //Get a list of all roles
        return Roles.GetAllRoles();

    }

Solution

  • Add a hidden field to the ItemTemplate as follows so that the Name(ID) can be found:

       <ItemTemplate>
       <tr>
        <asp:HiddenField runat="server" ID="Name" Value="<%# Item.Name %>" />
    

    Establish a reference to the repeater line through the TetChanged Event as shown below. Then use FindControl to find the ID and the required value. Update the Role information and then Databind to update the table:

    protected void ddRoles_TextChanged(object sender, EventArgs e)
    {
        var RepeaterItem = (sender as DropDownList).NamingContainer as RepeaterItem;
    
        var keyValue = RepeaterItem.FindControl("Name") as HiddenField;
    
        DataTable data = ViewState["Data"] as DataTable;
        var ddRoles = RepeaterItem.FindControl("ddRoles") as DropDownList;
    
        Roles.AddUserToRole(keyValue.Value, ddRoles.SelectedValue);
        repeaterManage.DataBind();
    
    }