问题
THE IDEA
I'm trying to do a very simple thing - refresh page when an item of the drop down list is selected. Selected item of the dropdownlist is passed to the query string as a parameter. Page reloads. Then parameter is taken from query string and used to restore selection of the drop down list. Parameter keeps the value of the selected item.
THE PROBLEM
Real selected value is not passed to the query string parameter, it's always "0". DropDownList never gets last selected item, it always restores the one which is saved in ViewState. ViewState doesn't want to remember new stuff, it always keeps one and the same info. I've been trying to find the solution for months. On some pages it works, but in most cases it doesn't. If it worked somewhere in my web app, I completely had no idea why and hoped it would continue working the next day. Sometimes it just stopped working and I wasn't able to fix it.
DEFAULT ASPX PAGE
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ExperimentalPage.aspx.cs"
Inherits="ExperimentalPage" Title="Enperimental Page" EnableViewState="True" %>
<asp:Content ID="ExperimentalLeftPane" ContentPlaceHolderID="cph_LeftPane" Runat="Server">
<div style="position: absolute; left: 0px; top: 35px; width: 250px;">
<asp:DropDownList ID="dd1" runat="server" OnSelectedIndexChanged="RefreshPage" AutoPostBack="True" CssClass="class_DropDown" Style="width: 250px; margin-bottom: 3px;"/>
</div>
</asp:Content>
DEFAULT ASPX.CS CODE-BEHIND PAGE
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dd1.Items.Insert(0, "dd1-0");
dd1.Items[0].Value = "0";
dd1.Items.Insert(1, "dd1-1");
dd1.Items[1].Value = "1";
dd1.Items.Insert(2, "dd1-2");
dd1.Items[2].Value = "2";
}
else
{
dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByValue(Convert.ToString(Request.QueryString["dd1"])));
}
}
protected void RefreshPage(object o, EventArgs e)
{
Page.Response.Redirect("ExperimentalPage.aspx?"
+ "&dd1=" + dd1.SelectedValue);
}
ATTEMPTS TO MAKE IT WORK
Scenario 1. EnableViewState="True"
I select third item (with value "2") of the dropdownlist, page reloads. Query string never takes the value "2". It always "0". The first item is always selected after postback, maybe because of ViewState, which resets it.
Scenario 2. EnableViewState="False"
Selected value is not saved. DropDownList is completely empty after postback.
Scenario 3. EnableViewState="False". Dropdownlist is filled with data on each page load. Postback is checked only for retrieving selected value:
protected void Page_Load(object sender, EventArgs e)
{
//if (!Page.IsPostBack)
//{
dd1.Items.Insert(0, "dd1-0");
dd1.Items[0].Value = "0";
dd1.Items.Insert(1, "dd1-1");
dd1.Items[1].Value = "1";
dd1.Items.Insert(2, "dd1-2");
dd1.Items[2].Value = "2";
//}
//else
if (Page.IsPostBack)
{
dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByValue(Convert.ToString(Request.QueryString["dd1"])));
}
}
In this case selected value is never saved to query string and dropdown selected item is never restored.
ONE BIG QUESTION
What do I miss and how to make it keep the selected value and restore it after postback?
THE PROBLEM PARTIALLY RESOLVED
See my answer
回答1:
Ok, I have realized how to fix it. If anybody needs it, this is the solution.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dd1.Items.Insert(0, "dd1-0");
dd1.Items[0].Value = "0";
dd1.Items.Insert(1, "dd1-1");
dd1.Items[1].Value = "1";
dd1.Items.Insert(2, "dd1-2");
dd1.Items[2].Value = "2";
}
}
protected void RefreshPage(object o, EventArgs e)
{
Session["dd1"] = dd1.SelectedValue;
dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByValue(Convert.ToString(Session["dd1"])));
}
In this solution EnableViewState page property is True. There is no Page redirection. Query string is not used. Instead, Session variable is used. This is a good way to keep values during postback.
回答2:
When you select an item from the dropdown, you will hit the Page_Load()
before the RefreshPage()
method
That means you will execute this line before the RefreshPage method:
dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByValue(Convert.ToString(Request.QueryString["dd1"])));
Convert.ToString(Request.QueryString["dd1"])) will evaluate to null, thus SelectedIndex will be set to 0.
If you want to make this work you should try the following:
if (!Page.IsPostBack)
{
dd1.Items.Insert(0, "dd1-0");
dd1.Items[0].Value = "0";
dd1.Items.Insert(1, "dd1-1");
dd1.Items[1].Value = "1";
dd1.Items.Insert(2, "dd1-2");
dd1.Items[2].Value = "2";
if (!string.IsNullOrEmpty(Request.QueryString["dd1"]))
{
dd1.SelectedIndex = dd1.Items.IndexOf(dd1.Items.FindByValue(Convert.ToString(Request.QueryString["dd1"])));
}
}
来源:https://stackoverflow.com/questions/17463937/restore-a-drop-down-selected-item-after-postback