离开页面时记住 Cascading Dropdown 值
Remember Cascading Dropdown value when navigating away from page
我为我的组织维护一个使用 Web 窗体的应用程序。我必须添加级联下拉菜单,并且我需要让这些下拉菜单在我离开页面时记住它们的值。我的第一个下拉菜单记住了它的值,但是当我向后导航时,它的级联下拉菜单不会保留它的值。有什么建议吗?
下面是我的下拉菜单:
<asp:UpdatePanel ID="updatePanel1" runat="server">
<ContentTemplate><div class="dropDownSelection">
<asp:DropDownList CssClass="topicDropDown" ID="topic1" DataTextField="NAME" DataValueField="ID" OnSelectedIndexChanged="Load_Section1" AutoPostBack="True" AppendDataBoundItems="true" runat="server"/>
<asp:DropDownList CssClass="sectionDropDown" ID="section1" DataTextField="NAME" DataValueFile="ID" AutoPostBack="True" runat="server">
<asp:ListItem Text="--- Select Section ---" Value="0"></asp:ListItem>
</asp:DropDownList></div><br/>
</ContentTemplate>
</asp:UpdatePanel>
以下是加载下拉值的方法:
protected void Load_Topic1()
{
var topicStore = new TopicStore();
var topics = topicStore.ReadTopics();
foreach (var topic in topics)
{
var topicListItem = new ListItem(topic.Name, topic.Id.ToString());
topic1.Items.Add(topicListItem);
//topic1.Attributes.Add("Title", topic.Description);//only shows description for item at the bottom of the dropdown
}
topic1.Items.Insert(0, new ListItem("--- Select Topic ---", "0"));
}
protected void Load_Section1(object sender, EventArgs e)
{
section1.Items.Clear();
var sectionStore = new SectionStore();
var sections = sectionStore.ReadForTopic(Guid.Parse(topic1.SelectedValue));
foreach (var section in sections)
{
var sectionListItem = new ListItem(section.Name, section.Id.ToString());
section1.Items.Add(sectionListItem);
}
section1.Items.Insert(0, new ListItem("--- Select Section ---", "0"));
}
Load_Topic1 在页面加载时调用。当您离开页面时,下拉菜单的值存储在会话中。
下面是我如何将值加载到会话中:
if (Session["Page"] != null)
{
if (Session["SubmittedPayment"] != null)
{
//shazbot -- they've already hit submit
Server.Transfer("default.aspx?logout=true");
}
topic1.SelectedValue = Session["topic1"] as string;
section1.SelectedValue = Session["section1"] as string;
rating1DropDown.SelectedValue = Session["rating1DropDown"] as string;
if (Session["Page"].ToString() == "HighSchoolInformation2.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else if (Session["Page"].ToString() == "Payment.aspx" || Session["Page"].ToString() == "InterestSurvey.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else
{
topic1.SelectedValue = Session["topic1"] as string;
section1.SelectedValue = Session["section1"] as string;
rating1DropDown.SelectedValue = Session["rating1DropDown"] as string;
Response.Redirect(Session["Page"].ToString());
}
}
else
{
//they're not logged in, send them back to log in
Server.Transfer("Default.aspx?logout=true");
}
在后面的代码中,我像这样加载会话变量:
protected void next_Click(object sender, EventArgs e)
{
Session.Add("topic1", topic1.SelectedValue);
Session.Add("section1", section1.SelectedValue);
Session.Add("rating1DropDown", rating1DropDown.SelectedValue);
Page.Validate();
if (Page.IsValid)
{
ModLangRequired.Visible = false;
if (!checkModLang())
{
Response.Redirect("Payment.aspx");
}
}
}
就像我在上面所说的那样,我继承了这段代码,目前我没有时间完全重写。
实际上发生的事情是,您的级联下拉列表(第 1 节)在选择的主题 1 上加载它的项目,当页面刷新时,主题 1 从托管 ViewState 获取它的值,第 1 节呈现空白...
有2种解决方案:
在脚本中管理
将 section1 的 selectedValue 存储在 ViewState 或 localStorage(浏览器存储)等任何存储中,并在文档准备就绪时,您可以通过 ajax 调用针对在 topic1 中选择的项目获取 section1 的项目并设置存储的选定值在存储中。 (听起来很努力,检查下面的选项)
后台代码管理
在您的 Page_Load 方法中,调用 Load_Section1 并传递 topic1.SelectedValue
不要忘记输入 Page.IsPostBack 条件以避免错误...
首先按如下方式更改 Load_Section1
。请注意我们如何使用 Guid.TryParse
在选择主题时有条件地加载部分。
protected void Load_Section1()
{
section1.Items.Clear();
section1.Items.Add(new ListItem("--- Select Section ---", "0"));
Guid topicId;
if (Guid.TryParse(topic1.SelectedValue, out topicId))
{
var sectionStore = new SectionStore();
var sections = sectionStore.ReadForTopic(topicId);
foreach (var section in sections)
{
var sectionListItem = new ListItem(section.Name, section.Id.ToString());
section1.Items.Add(sectionListItem);
}
}
}
然后添加一个新的事件处理器如下:
protected void TopicDropDown_OnSelectedIndexChanged(object sender, EventArgs e)
{
Load_Section1();
}
现在将 OnSelectedIndexChanged
事件关联到新的处理程序:
<asp:DropDownList ID="topic1" ... OnSelectedIndexChanged="TopicDropDown_OnSelectedIndexChanged" ... />
现在可以恢复页面状态如下:
if (Session["Page"] != null)
{
if (Session["SubmittedPayment"] != null)
{
//shazbot -- they've already hit submit
Server.Transfer("default.aspx?logout=true");
}
Load_Topic1();
topic1.SelectedValue = IsPostBack ? Request.Form[topic1.UniqueID] : (string)Session["topic1"];
Load_Section1();
section1.SelectedValue = IsPostBack ? Request.Form[section1.UniqueID] : (string)Session["section1"];
Load_Rating1DropDown(); // not sure if you need this???
rating1DropDown.SelectedValue = IsPostBack ? Request.Form[rating1DropDown.UniqueID] : (string)Session["rating1DropDown"];
if (Session["Page"].ToString() == "HighSchoolInformation2.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else if (Session["Page"].ToString() == "Payment.aspx" || Session["Page"].ToString() == "InterestSurvey.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else
{
// you don't actually need to set values before you redirect
Response.Redirect(Session["Page"].ToString());
}
}
else
{
//they're not logged in, send them back to log in
Server.Transfer("Default.aspx?logout=true");
}
我的假设是上面的代码是从 Page_Load
调用的。避免对 Load_Topic1
进行任何额外调用。
我为我的组织维护一个使用 Web 窗体的应用程序。我必须添加级联下拉菜单,并且我需要让这些下拉菜单在我离开页面时记住它们的值。我的第一个下拉菜单记住了它的值,但是当我向后导航时,它的级联下拉菜单不会保留它的值。有什么建议吗?
下面是我的下拉菜单:
<asp:UpdatePanel ID="updatePanel1" runat="server">
<ContentTemplate><div class="dropDownSelection">
<asp:DropDownList CssClass="topicDropDown" ID="topic1" DataTextField="NAME" DataValueField="ID" OnSelectedIndexChanged="Load_Section1" AutoPostBack="True" AppendDataBoundItems="true" runat="server"/>
<asp:DropDownList CssClass="sectionDropDown" ID="section1" DataTextField="NAME" DataValueFile="ID" AutoPostBack="True" runat="server">
<asp:ListItem Text="--- Select Section ---" Value="0"></asp:ListItem>
</asp:DropDownList></div><br/>
</ContentTemplate>
</asp:UpdatePanel>
以下是加载下拉值的方法:
protected void Load_Topic1()
{
var topicStore = new TopicStore();
var topics = topicStore.ReadTopics();
foreach (var topic in topics)
{
var topicListItem = new ListItem(topic.Name, topic.Id.ToString());
topic1.Items.Add(topicListItem);
//topic1.Attributes.Add("Title", topic.Description);//only shows description for item at the bottom of the dropdown
}
topic1.Items.Insert(0, new ListItem("--- Select Topic ---", "0"));
}
protected void Load_Section1(object sender, EventArgs e)
{
section1.Items.Clear();
var sectionStore = new SectionStore();
var sections = sectionStore.ReadForTopic(Guid.Parse(topic1.SelectedValue));
foreach (var section in sections)
{
var sectionListItem = new ListItem(section.Name, section.Id.ToString());
section1.Items.Add(sectionListItem);
}
section1.Items.Insert(0, new ListItem("--- Select Section ---", "0"));
}
Load_Topic1 在页面加载时调用。当您离开页面时,下拉菜单的值存储在会话中。
下面是我如何将值加载到会话中:
if (Session["Page"] != null)
{
if (Session["SubmittedPayment"] != null)
{
//shazbot -- they've already hit submit
Server.Transfer("default.aspx?logout=true");
}
topic1.SelectedValue = Session["topic1"] as string;
section1.SelectedValue = Session["section1"] as string;
rating1DropDown.SelectedValue = Session["rating1DropDown"] as string;
if (Session["Page"].ToString() == "HighSchoolInformation2.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else if (Session["Page"].ToString() == "Payment.aspx" || Session["Page"].ToString() == "InterestSurvey.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else
{
topic1.SelectedValue = Session["topic1"] as string;
section1.SelectedValue = Session["section1"] as string;
rating1DropDown.SelectedValue = Session["rating1DropDown"] as string;
Response.Redirect(Session["Page"].ToString());
}
}
else
{
//they're not logged in, send them back to log in
Server.Transfer("Default.aspx?logout=true");
}
在后面的代码中,我像这样加载会话变量:
protected void next_Click(object sender, EventArgs e)
{
Session.Add("topic1", topic1.SelectedValue);
Session.Add("section1", section1.SelectedValue);
Session.Add("rating1DropDown", rating1DropDown.SelectedValue);
Page.Validate();
if (Page.IsValid)
{
ModLangRequired.Visible = false;
if (!checkModLang())
{
Response.Redirect("Payment.aspx");
}
}
}
就像我在上面所说的那样,我继承了这段代码,目前我没有时间完全重写。
实际上发生的事情是,您的级联下拉列表(第 1 节)在选择的主题 1 上加载它的项目,当页面刷新时,主题 1 从托管 ViewState 获取它的值,第 1 节呈现空白...
有2种解决方案:
在脚本中管理
将 section1 的 selectedValue 存储在 ViewState 或 localStorage(浏览器存储)等任何存储中,并在文档准备就绪时,您可以通过 ajax 调用针对在 topic1 中选择的项目获取 section1 的项目并设置存储的选定值在存储中。 (听起来很努力,检查下面的选项)
后台代码管理
在您的 Page_Load 方法中,调用 Load_Section1 并传递 topic1.SelectedValue
不要忘记输入 Page.IsPostBack 条件以避免错误...
首先按如下方式更改 Load_Section1
。请注意我们如何使用 Guid.TryParse
在选择主题时有条件地加载部分。
protected void Load_Section1()
{
section1.Items.Clear();
section1.Items.Add(new ListItem("--- Select Section ---", "0"));
Guid topicId;
if (Guid.TryParse(topic1.SelectedValue, out topicId))
{
var sectionStore = new SectionStore();
var sections = sectionStore.ReadForTopic(topicId);
foreach (var section in sections)
{
var sectionListItem = new ListItem(section.Name, section.Id.ToString());
section1.Items.Add(sectionListItem);
}
}
}
然后添加一个新的事件处理器如下:
protected void TopicDropDown_OnSelectedIndexChanged(object sender, EventArgs e)
{
Load_Section1();
}
现在将 OnSelectedIndexChanged
事件关联到新的处理程序:
<asp:DropDownList ID="topic1" ... OnSelectedIndexChanged="TopicDropDown_OnSelectedIndexChanged" ... />
现在可以恢复页面状态如下:
if (Session["Page"] != null)
{
if (Session["SubmittedPayment"] != null)
{
//shazbot -- they've already hit submit
Server.Transfer("default.aspx?logout=true");
}
Load_Topic1();
topic1.SelectedValue = IsPostBack ? Request.Form[topic1.UniqueID] : (string)Session["topic1"];
Load_Section1();
section1.SelectedValue = IsPostBack ? Request.Form[section1.UniqueID] : (string)Session["section1"];
Load_Rating1DropDown(); // not sure if you need this???
rating1DropDown.SelectedValue = IsPostBack ? Request.Form[rating1DropDown.UniqueID] : (string)Session["rating1DropDown"];
if (Session["Page"].ToString() == "HighSchoolInformation2.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else if (Session["Page"].ToString() == "Payment.aspx" || Session["Page"].ToString() == "InterestSurvey.aspx")
{
Session.Add("Page", "InterestSurvey.aspx");
}
else
{
// you don't actually need to set values before you redirect
Response.Redirect(Session["Page"].ToString());
}
}
else
{
//they're not logged in, send them back to log in
Server.Transfer("Default.aspx?logout=true");
}
我的假设是上面的代码是从 Page_Load
调用的。避免对 Load_Topic1
进行任何额外调用。