简体   繁体   中英

DropDownList in User Control loses SelectedValue on first postback when loaded dynamically

I have an ASPX page that has a PlaceHolder in which User Controls are loaded dynamically. HTML markup is as follows:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="Test" %>

<!DOCTYPE html>

<html>
<head runat="server">
</head>
<body>
    <form id="form1" runat="server">

        <asp:Button ID="btnNumbers" Text="Select Numbers" OnClick="SelectNumbers" runat="server" />
        <br /><br />
        <asp:Button ID="btnLetters" Text="Select Letters" OnClick="SelectLetters" runat="server" />
        <br /><br />

        <asp:PlaceHolder ID="phContent" runat="server" />

    </form>
</body>
</html>

The Code Behind is as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;


public partial class Test : System.Web.UI.Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        if (!IsPostBack)
            HttpContext.Current.Session["control"] = "~/Controls/Numbers.ascx";
        LoadControl();        
    }

    protected void SelectNumbers(object sender, EventArgs e)
    {
        HttpContext.Current.Session["control"] = "~/Controls/Numbers.ascx";
        LoadControl();
    }

    protected void SelectLetters(object sender, EventArgs e)
    {
        HttpContext.Current.Session["control"] = "~/Controls/Letters.ascx";
        LoadControl();
    }

    private void LoadControl()
    {
        phContent.Controls.Clear();
        var control = Page.LoadControl((String)HttpContext.Current.Session["control"]);
        phContent.Controls.Add(control);
    }
}

The first user control has a DropDownList to select numbers. It has markup as follows:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Numbers.ascx.cs" Inherits="Numbers" %>


<asp:DropDownList ID="ddlSelectNumbers"
                  AutoPostBack="true" runat="server"
                  OnSelectedIndexChanged="SelectNumbers_IndexChanged" >
    <asp:ListItem Text="One" Value="1" />
    <asp:ListItem Text="Two" Value="2" />
    <asp:ListItem Text="Three" Value="3" />
</asp:DropDownList>

<br /><br />

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

And Code Behind as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using Superexpert.Controls;


public partial class Numbers : System.Web.UI.UserControl
{
    public override String ID
    {
        get { return "Numbers"; }
        set { }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void SelectNumbers_IndexChanged(object sender, EventArgs e)
    {
        lblSelectedNumber.Text = ((DropDownList)sender).SelectedItem.Text;
    }
}

The second user control has a DropDownList to select letters. It has markup as follows:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Letters.ascx.cs" Inherits="Letters" %>



<asp:DropDownList ID="ddlSelectLetters"
                  AutoPostBack="true" runat="server"
                  OnSelectedIndexChanged="SelectLetters_IndexChanged" >
    <asp:ListItem Text="A" Value="a" />
    <asp:ListItem Text="B" Value="b" />
    <asp:ListItem Text="C" Value="c" />
</asp:DropDownList>

<br /><br />

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

And Code Behind as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using Superexpert.Controls;


public partial class Letters : System.Web.UI.UserControl
{
    public override String ID
    {
        get { return "Letters"; }
        set { }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void SelectLetters_IndexChanged(object sender, EventArgs e)
    {
        lblSelectedLetter.Text = ((DropDownList)sender).SelectedItem.Text;
    }
}

Everything works find when the page first loads (!IsPostBack). You can select numbers from the DropDownList and it's SelectedItemChanged event fires, it's SelectedValue is updated, and the Label is updated.

The problem happens when you click one of the buttons to dynamically load one of the user controls. After that, the first time you select something from the DropDownList, the SelectedItemChanged event doesn't fire, it's SelectedValue is not updated, and therefore Label is not updated. Afterwards, everything works fine.

What is causing this to happen?

Thanks in advance!

You are very closed. You just need to assign ID to dynamically created control.

Basically, you need to assign ID to dynamically created control, if you want to retrieve them on post back.

Look at 3 <--- in the following code.

public partial class Test : System.Web.UI.Page
{
   ... Same as above

    private void LoadControl()
    {
        phContent.Controls.Clear();
        var control = Page.LoadControl((String)HttpContext.Current.Session["control"]);
        control.ID = "1"; <--- 1. Control ID is required. 
        phContent.Controls.Add(control);
    }
}

public partial class Numbers : System.Web.UI.UserControl
{
    // public override String ID ... <--- 2. Remove this

    protected void SelectNumbers_IndexChanged(object sender, EventArgs e)
    {
        lblSelectedNumber.Text = ((DropDownList)sender).SelectedItem.Text;
    }
}

public partial class Letters : System.Web.UI.UserControl
{
    // public override String ID ... <--- 3. Remove this

    protected void SelectLetters_IndexChanged(object sender, EventArgs e)
    {
        lblSelectedLetter.Text = ((DropDownList)sender).SelectedItem.Text;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM