C# – asp.net asp:DropDownList onSelectedIndexChanged not firing in databound asp:GridView

asp.netcdataboundeventsgridview

I'm having troubles with this and I can't figure it out.
I have a databound asp:gridview (sqldatasource) with an asp:dropdownlist inside an itemtemplate. The dropdownlist has an onSelectedIndexChanged event listener but it doesn't fire.

Here's the markup:

<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="UpdatePanel1">
    <ContentTemplate>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        EmptyDataText="There are no data records to display." EnableViewState="True" >
        <Columns>
            <asp:TemplateField HeaderText="Delete user">
                <ItemTemplate>
                    <asp:Button runat="server" ID="btnDelete" CommandName="Delete" CommandArgument='<%# Eval("UserId") %>'
                        Text="Delete" OnCommand="DeleteUser" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Block users">
                <ItemTemplate>
                    <asp:Button runat="server" ID="btnBlock" CommandName="Block" CommandArgument='<%# Eval("UserId") %>'
                        Text="Block" OnClick="btnBlock_Click" Visible='<%# !Convert.ToBoolean(Eval("IsLockedOut")) %>' />
                    <asp:Button runat="server" ID="btnDeblock" CommandName="Deblock" CommandArgument='<%# Eval("UserId") %>'
                        Text="Deblock" OnClick="btnBlock_Click" Visible='<%# Convert.ToBoolean(Eval("IsLockedOut")) %>' />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Change role">
                <ItemTemplate>
                    <asp:DropDownList ID="ChangeRole" runat="server" EnableViewState="false"
                        OnSelectedIndexChanged="ChangeRole_SelectedIndexChanged" AutoPostBack="true"
                        ToolTip='<%# Bind("UserName") %>' >
                        <asp:ListItem Text="Choose a role" Value="" Selected="True" />
                        <asp:ListItem Text="Admin" Value="" />
                        <asp:ListItem Text="Member" Value="" />
                        <asp:ListItem Text="Visitor" Value="" />
                    </asp:DropDownList>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="RoleName" HeaderText="Current role" ReadOnly="true" SortExpression="RoleName" />
            <asp:BoundField DataField="UserName" HeaderText="Username" ReadOnly="True" SortExpression="UserName" />
            <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
            <asp:BoundField DataField="LastLoginDate" HeaderText="Last login" 
                SortExpression="LastLoginDate" />
            <asp:CheckBoxField DataField="IsLockedOut" HeaderText="Locked" 
                SortExpression="IsLockedOut" />
            <asp:BoundField DataField="FailedPasswordAttemptCount" 
                HeaderText="Failed logins" 
                SortExpression="FailedPasswordAttemptCount" />
            <asp:BoundField DataField="Comment" HeaderText="Comments" 
                SortExpression="Comment" />
        </Columns>
    </asp:GridView>
    <asp:Label ID="lblSuccess" runat="server" Text="Database updated successfully." Visible="false" meta:resourcekey="success" />
    <asp:Label ID="lblError" runat="server" Text="An error occured, database was not updated." />
    </ContentTemplate>
</asp:UpdatePanel>

I've added the updatepanel code because I figured it might be relevant.
In the code behind, I made sure to bind the gridview only if !Page.IsPostBack

protected void Page_Load(object sender, EventArgs e)
{

    if (!Page.IsPostBack)
    {
        GridView1.DataSourceID = "SqlDataSource1";
        GridView1.DataKeyNames = new String[] {"UserId"};
        GridView1.DataBind();
    }
}

Then I made an actionlistener for the dropdownlist

protected void ChangeRole_SelectedIndexChanged(object sender, EventArgs e)
{
    Logger.Info("it's alive!", "Chaning role");
}

I already tried enableViewState="True || False" (for both gridview and dropdownlist) and autoPostBack="True || False" in both directions but the logfile doesn't show the "It's alive" message. The event hasn't been triggered on changing index.

Any ideas?

Best Answer

Alright,

I've finally found the solution. Searching the internet reveals this is not an uncommon problem. The solution however, is never too far away.

First I changed everything on my page (including page directive, gridview, updatetemplate and dropdownlist) to EnableViewState="true", Then I set the AutoPostBack="true" on my dropdownlist, Finally, I need to make sure that I'm not binding the gridview with it's data in the page_load method because this phase in the lifecycle already rebinds the dropdownlists and sets their selectedindex back to default before the onselectedindexchanged event can be fired.

I just let the gridview do the binding as usual by setting it's datasourceid. During my search, I've seen many people with a similar issue and I think this should fix a lot of them. Or at least it's worth a shot :)

Related Topic