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?

有帮助吗?

解决方案

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

其他提示

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!

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.

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.

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

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)
{
}

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top