DerpyNerd
DerpyNerd

Reputation: 4803

asp.net asp:DropDownList onSelectedIndexChanged not firing in databound asp:GridView

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?

Upvotes: 0

Views: 34298

Answers (7)

Serb
Serb

Reputation: 21

This solved my problem: CausesValidation="False" Here are the details.

Upvotes: 1

Binary Thoughts
Binary Thoughts

Reputation: 33

Though this is an old article I hope it still contributes.

I had the same problem, for me the solution was to set values for the "Value" property of a ListItems. So change the code as follows:

<asp:DropDownList ID="ChangeRole" runat="server" EnableViewState="false" 
OnSelectedIndexChanged="ChangeRole_SelectedIndexChanged" AutoPostBack="true"                       ToolTip='<%# Bind("UserName") %>' >
<asp:ListItem Text="Choose a role" Value="0" Selected="True" />
<asp:ListItem Text="Admin" Value="1" />
<asp:ListItem Text="Member" Value="2" />
<asp:ListItem Text="Visitor" Value="3" />
</asp:DropDownList>

Hope this will help someone.

Upvotes: 0

Camathon
Camathon

Reputation: 524

Like you said its not an uncommon problem. I had the same problem myself, therefore I'd like to contribute with a check list to rule out some more common problems:

  • Make sure ViewState is activated, EnableViewState="True"
  • If above point doesn't work also check if any parent element has ViewState disabled
  • Activate post back AutoPostBack="True"
  • Make sure your dababining takes place only if its not a postback if(!Page.IsPostBack), ViewState will save the chosen option and for your form (if you have one)

That's all I could think of for now :) hope it helps anyone!

Upvotes: 4

writeToBhuwan
writeToBhuwan

Reputation: 3281

Set the AutoPostBack="true" for the DropDownList.

and set the updatemode of update panel to always like this

<asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Always">

Or set a trigger which handles the SelectedIndexChanged event of the DropDownList.

Upvotes: 1

DerpyNerd
DerpyNerd

Reputation: 4803

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

Upvotes: 6

Mark Vickery
Mark Vickery

Reputation: 1955

have you tried changing the view state of the DropDownList to "true":

<asp:DropDownList ID="ChangeRole" runat="server" EnableViewState="true" OnSelectedIndexChanged="ChangeRole_SelectedIndexChanged" AutoPostBack="true" ...

if the state of the drop down is being forgotten between postbacks then the index wont have changed, hence the SelectedIndexChange event not firing.

Upvotes: 1

Aram Beginyan
Aram Beginyan

Reputation: 294

Try change GridView like this

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" EmptyDataText="There are no data records to display." EnableViewState="True" DataSource="SqlDataSource1" DataKeyNames="UserId" >

clear the Page_Load function

protected void Page_Load(object sender, EventArgs e)
{
}

Upvotes: 0

Related Questions