动态创建级联下拉列表

时间:2018-04-03 13:40:05

标签: c# asp.net cascadingdropdown

这个问题对某些人来说可能是微不足道的,但对于我的生活,我似乎无法弄明白。

设定: 我在设计时添加了一个下拉列表( DropDownList1 )。 DropDownList1 会根据所选值在运行时动态创建其他下拉列表( DDL1,DDL2,DDL3 )。每个回发都会生成下拉列表项作为默认值。一些动态创建的下拉列表( DLL2,DDL3 )也是级联下拉列表,其中 DDL3 数据项基于 DDL2 所选项生成。我在 DDL2 上有 onSelectedIndexChanged 事件,以生成 DDL3 的数据项。

问题: DDL1 DDL2 选择的值会在回发时保留,这是有意义的,因为它是在onpageload上生成的。 DDL3 会根据 DDL2 选项显示正确的数据项,但在选择值后,该页面会回发并丢失所选值。

标记:

            <asp:UpdatePanel ID="upanel" runat="server">
                <ContentTemplate>
                    <div class="container1">
                        <div id="params-container" class="container">
                            <asp:DropDownList ID="DropDownList1" runat="server" CssClass="input-fields" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" AutoPostBack="true"></asp:DropDownList>
                            <asp:PlaceHolder ID="DatesPh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="SeasonPh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="CompanyPh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="BrandPh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="LocationPh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="GenderPh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="LinePh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="SubLinePh" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:PlaceHolder ID="PlaceHolder1" runat="server" EnableViewState="false"></asp:PlaceHolder>
                            <asp:Button ID="Button1" runat="server" Text="Show" OnClick="Button1_Click" class="input-button" />
                        </div>
                    </div>
                </ContentTemplate>
            </asp:UpdatePanel>

代码背后:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        using (SqlConnection cn = new SqlConnection(connStr))
        {
//This is my design time dropdown.
//List item is generated only on first request.
//It has AutoPostBack=true so that new controls will be created based on the selection.

            DropDownList1.DataSource =  GetSqlData("sp_getReports",null);
            DropDownList1.DataTextField = "ReportName";
            DropDownList1.DataValueField = "ReportNum";
            DropDownList1.DataBind();
            DropDownList1.Items.Insert(0, new ListItem("Select a report", ""));
            DropDownList1.SelectedIndex = 0;
        }
    }

//This is where I create all controls dynamically (some tb and some ddl).
//I am also generating the list items for the ddl here dynamically.  
//Everything happens on pageload.

using (SqlConnection con = new SqlConnection(connStr))
{

    using (SqlCommand cmd = new SqlCommand("sp_fieldTableMap", con))
    {
        DataTable dtable = new DataTable();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@inputRpt", DropDownList1.SelectedValue);
        SqlDataAdapter adp = new SqlDataAdapter(cmd);
        adp.Fill(dtable);

        foreach (DataRow dr in dtable.Rows)
        {
            if (dr["SqlQuery"].ToString().Trim() == "")
            {
                TextBox tb = new TextBox();
                tb.ID = dr["AspId"].ToString().Trim();
                tb.CssClass = "input-fields";
                tb.Attributes.Add("placeholder", dr["FieldName"].ToString().Trim());

                Control chkPh = FindControl(dr["Container"].ToString().Trim());
                if (chkPh is PlaceHolder)
                {
                    PlaceHolder pHolder = chkPh as PlaceHolder;
                    pHolder.Controls.Add(tb);
                }
            }
            else
            {
                DropDownList ddl = new DropDownList();
                ddl.ID = dr["AspId"].ToString().Trim();
                ddl.CssClass = "input-fields";
                ddl.AutoPostBack = true;

//I am dynamically creating the selectedindexchanged event
//for one of my ddl to provide cascading dropdown functionality on another dropdown.
                        if (ddl.ID == "brandCode")
                        {    
                ddl.SelectedIndexChanged += new EventHandler(brandCode_SelectedIndexChanged);
                        }
                        if (ddl.ID == "genderCode")
                        {
                            ddl.SelectedIndexChanged += new EventHandler(genderCode_SelectedIndexChanged);
                        } 
                Control chkPh = FindControl(dr["Container"].ToString().Trim());
                if (chkPh is PlaceHolder)
                {
                    PlaceHolder pHolder = chkPh as PlaceHolder;
                    pHolder.Controls.Add(ddl);
                }

                using (SqlConnection cn = new SqlConnection(connStr))
                {

//As I said, I generate the dropdown data items on pageload

                    DataTable sqlTab = new DataTable();
                    SqlCommand sqlCmd = new SqlCommand(dr["SqlQuery"].ToString().Trim(), cn);
                    sqlCmd.CommandType = CommandType.Text;
                    SqlDataAdapter sqlAdp = new SqlDataAdapter(sqlCmd);
                    sqlAdp.SelectCommand.CommandTimeout = 60;
                    sqlAdp.Fill(sqlTab);
                    ddl.DataSource = sqlTab;

                    ddl.DataTextField = dr["DdlText"].ToString().Trim();
                    ddl.DataValueField = dr["DdlValue"].ToString().Trim();
                    ddl.DataBind();
                    ddl.Items.Insert(0, new ListItem("", ""));

//Chidambaram's modified code added after databind of "DDL3"

                    if (ddl.ID == "genderCode") { ddl.SelectedValue = ddlValue; }

                }
            }
        }
    }
}
}
//End of pageload

public String ddlValue
{
    get
    {
        if (ViewState["ddlValue"] == null)
        {
            ViewState["ddlValue"] = String.Empty;
        }
        return ViewState["ddlValue"].ToString();
    }
    set
    {
        ViewState["ddlValue"] = value;
    }
}


//Also added an event for "DDL3" selectedindex to assign its value to the viewstate

    protected void genderCode_SelectedIndexChanged(object sender, EventArgs e)
    {
        Control chkGender = FindControl("genderCode");
        if (chkGender is DropDownList)
        {
            DropDownList ddlGender = chkGender as DropDownList;
            if (ddlGender.SelectedValue == "-1")
            {

            }
            else
            {
                ddlValue = ddlGender.SelectedValue;
            }
        }
    }


protected void brandCode_SelectedIndexChanged(object sender, EventArgs e)
{

//Cascading Dropdown: This event generates the data item of one dropdown based on its selection.
//This runs successfully, gender dropdown only displays the appropriate items based on the brand dropdown.

    Control chkBrand = FindControl("brandCode");
    if (chkBrand is DropDownList)
    {
        DropDownList ddlBrand = chkBrand as DropDownList;
        if (ddlBrand.SelectedValue == "-1")
        {
        }
        else
        {
            SqlParameter param = new SqlParameter();
            param.ParameterName = "@brandCode";
            param.Value = ddlBrand.SelectedValue;    
            Control chkGender = FindControl("genderCode");
            if (chkGender is DropDownList)
            {
                DropDownList ddlGender = chkGender as DropDownList;
                ddlGender.DataSource = GetSqlData("sp_getGender", param);
                ddlGender.DataBind();
                ddlGender.Items.Insert(0, new ListItem("", ""));
                ddlGender.SelectedIndex = 0;
            }
        }
    }
}

private DataSet GetSqlData(string SpName, SqlParameter SpParam)
{
    SqlConnection con = new SqlConnection(connStr);
    SqlDataAdapter da = new SqlDataAdapter(SpName, con);
    da.SelectCommand.CommandType = CommandType.StoredProcedure;
    if (SpParam != null)
    {
        da.SelectCommand.Parameters.Add(SpParam);
    }
    DataSet DS = new DataSet();
    da.Fill(DS);
    return DS;
}

非常感谢任何帮助。感谢。

添加了一些评论。

1 个答案:

答案 0 :(得分:0)

您可以使用如下所示的viewstate来设置和获取值。一旦使用该值,则将其设置为空或null。

 public String ddlValue
    {
        get
        {
            if (ViewState["ddlValue"] == null)
            {
                ViewState["ddlValue"] = String.Empty;
            }
            return ViewState["ddlValue"].ToString();
        }
        set
        {
            ViewState["ddlValue"] = value;
        }
    }

public void Page_Load(object sender, EventArgs e)
{
    if (this.ddlValue!=null)
    {
        //set the value here in ddl
        ddl3.selectedvalue=ddlValue;
    }
}