DropDownList OnSelectedIndexChanged event stops wo

2019-08-04 07:03发布

问题:

I have a page with a repeater. Inside each item of that repeater are update panels, each containing a control:

<asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%# Eval("Property1") %>' />
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostback="true"
                    OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
                    <asp:ListItem Text="1" Value="1" />
                    <asp:ListItem Text="2" Value="2" />
                    <asp:ListItem Text="3" Value="3" />
                    <asp:ListItem Text="4" Value="4" />
                </asp:DropDownList>
            </ContentTemplate>
        </asp:UpdatePanel>
    </ItemTemplate>
</asp:Repeater>

The code behind supplies the data source:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            List<Class1> Source = new List<Class1>();
            Source.Add(new Class1("Test1"));
            Source.Add(new Class1("Test2"));
            Source.Add(new Class1("Test3"));
            Repeater1.DataSource = Source;
            Repeater1.DataBind();
        }
    }

And here is the class being bound:

public class Class1
{
    public string Property1 { get; set; }
    public string Property2 { get { return "Property 2"; } }
    public Class1() { Property1 = string.Empty; }
    public Class1(string P1) { Property1 = P1; }
}

And when the drop down list selected index is changed, this is the event that fires in the code behind:

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList ddl = (DropDownList)sender;
        RepeaterItem ri = (RepeaterItem)ddl.NamingContainer;
        Label l = (Label)ri.FindControl("Label1");

        l.Text = ddl.SelectedValue;

        UpdatePanel up = (UpdatePanel)ri.FindControl("UpdatePanel1");
        up.Update();
    }

All of this code works just fine. When the selected index is changed, the label text is updated to match, and everything is happy.

The problem is when I add a user control to the repeater. It doesn't seem to matter what the user control does, but here is a simple example I used to break this sample code:

Front:

<asp:Label ID="Label1" runat="server" />

Back:

public partial class WebUserControl1 : System.Web.UI.UserControl
{
    private Class1 _Item = null;
    public Class1 Item { get { return _Item; } set { _Item = value; } }

    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = Item.Property1;
    }
}

When I register this user control on the page:

<%@ Register Src="WebUserControl1.ascx" TagName="Control1" TagPrefix="uc1" %>

And place it inside the repeater in its own update panel:

<asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%# Eval("Property1") %>' />
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <uc1:Control1 ID="Control1" runat="server" Item='<%# ((IDataItemContainer)Container).DataItem %>' />
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostback="true"
                    OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
                    <asp:ListItem Text="1" Value="1" />
                    <asp:ListItem Text="2" Value="2" />
                    <asp:ListItem Text="3" Value="3" />
                    <asp:ListItem Text="4" Value="4" />
                </asp:DropDownList>
            </ContentTemplate>
        </asp:UpdatePanel>
    </ItemTemplate>
</asp:Repeater>

The user control paints correctly (suggesting it is working), but the OnSelectedIndexChanged event stops firing. Even inserting System.Diagnostics.Debugger.Break() inside the event doesn't fire. Everything else (the event code, the page load, the class) all remain the same. The only difference is adding this user control to the page and repeater.

Can anyone tell me why the introduction of this (seemingly unrelated) user control seems to break the DropDownList behavior?

Thanks for any help!

EDIT: Answered. I was just missing a Page.IsPostBack test in the Page_Load event of WebUserControl1. Silly mistake.

回答1:

Yeah I had similar exact issue, if you dont check the !IsPostback property on the page load , then the control is rebound again and there fore the other controls inside like the dropdownlist is also rebound and reinitialized and thus the event is not fired