动态创建的级联下拉列表 [英] Dynamically created cascading dropdown lists

查看:77
本文介绍了动态创建的级联下拉列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题对于某些人来说可能是微不足道的,但是对于我的一生来说,我似乎无法弄清楚.

This issue might be trivial for some but for the life of me, I cannot seem to figure it out.

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

Setup: I have a dropdown (DropDownList1) added at design time. DropDownList1 dynamically creates other dropdowns (DDL1, DDL2, DDL3) at runtime based on the selected value. The dropdown list items is generated every postback as default values. Some of the dynamically created dropdowns (DLL2, DDL3) are also cascading dropdowns wherein DDL3 data items are generated based on DDL2 selected item. I have an onSelectedIndexChanged event on DDL2 to generate data items for DDL3.

问题:选择的 DDL1 DDL2 值将保留在回发中,这是有道理的,因为它是在页面加载时生成的. DDL3 根据 DDL2 选择显示正确的数据项,但是选择一个值后,页面会回发并丢失所选的值.

Problem: DDL1 and DDL2 selected values are retained on postback, which makes sense since it is generated onpageload. DDL3 shows the correct data items based on the DDL2 selection, but upon selecting a value, the page posts back and loses the selected value.

标记:

            <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;
}

任何帮助将不胜感激.谢谢.

Any help is greatly appreciated. Thanks.

添加了一些评论.

推荐答案

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

You can use the viewstate like below to set and get the value. once the value is utilized, then set it to empty or 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;
    }
}

这篇关于动态创建的级联下拉列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆