【发布时间】:2018-09-12 20:54:35
【问题描述】:
这个问题对某些人来说可能是微不足道的,但对于我的生活,我似乎无法弄清楚。
设置: 我在设计时添加了一个下拉列表 (DropDownList1)。 DropDownList1 在运行时根据所选值动态创建其他下拉列表(DDL1、DDL2、DDL3)。每次回发都会生成下拉列表项作为默认值。一些动态创建的下拉菜单(DLL2、DDL3)也是级联下拉菜单,其中 DDL3 数据项是根据 DDL2 选定项生成的。我在 DDL2 上有一个 onSelectedIndexChanged 事件来为 DDL3 生成数据项。
问题: DDL1 和 DDL2 选定的值在回发时保留,这是有道理的,因为它是在页面加载时生成的。 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;
}
非常感谢任何帮助。谢谢。
添加了一些 cmets。
【问题讨论】:
-
如果您在 DDL3 选择上进行回发,只需将选定的 DDL3 数据保存在视图状态中,并在页面加载时使用相同的视图状态值设置为 DDL3。如果值为空,则不分配。
-
确保页面加载时存在任何动态控件,否则值不会丢失。我猜你正在失去价值,因为你得到了错误的控制。使用将成为下拉列表控件的“发送者”对象,而不是“FindControl”。
-
感谢您的意见。 @Chidambaram我正在使用asp.net服务器控件,如果我没记错的话,那不是已经在内部支持视图状态了吗?只是一个观察,但我对视图状态的解释可能是错误的。
-
@ATerry 我不确定您所说的“发件人”对象是什么意思。你介意详细说明吗?谢谢。
-
事件参数'sender'是发送事件的控件。
标签: c# asp.net cascadingdropdown