c#ASP.Net动态填充的DropDownList会在提交按钮上丢失选定的索引

时间:2012-03-08 14:22:21

标签: c# asp.net drop-down-menu selectedindex

我从PageLoad上的ArrayList动态填充所有50个状态的下拉列表。当用户选择SUBMIT按钮(btnSubmit_Click事件)时,尽管用户选择了什么选项,下拉列表控件的SelectedIndex属性始终为0。


添加了更多代码以帮助进行故障排除。从会话变量(bbb)和ddlState.selectedindex(bbb)获得-1。

表单中的HTML代码:

<asp:DropDownList ID="ddlState" runat="server" AutoPostBack="True" 
    onselectedindexchanged="ddlState_SelectedIndexChanged" >
</asp:DropDownList>

代码背后:

protected void Page_Load(object sender, EventArgs e)
{
    //------------------------------------------------
    // Populates state dropdownlists
    //------------------------------------------------
    if (!IsPostBack)
    {
        GetAllStatesForDdl(ddlDLState);
        GetAllStatesForDdl(ddlOldState);
        GetStatesForDdl(ddlState);
    }
}

private void GetAllStatesForDdl(DropDownList ddlStateList)
{
    AppInputFormProcessor getStates = new AppInputFormProcessor();
    ArrayList States = new ArrayList();
    States = getStates.GetAllStates();
    ddlStateList.DataSource = States;
    ddlStateList.DataBind();
}

private void GetStatesForDdl(DropDownList ddlStateList)
{
    AppInputFormProcessor getStates = new AppInputFormProcessor();
    ArrayList States = new ArrayList();
    States = getStates.GetStates();
    ddlStateList.DataSource = States;
    ddlStateList.DataBind();
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
    int aaa = ddlState.SelectedIndex;
    int bbb = Convert.ToInt32(Session["ddlState"]);
}

protected void ddlState_SelectedIndexChanged(object sender, EventArgs e)
{
    Session["ddlState"] = ddlState.SelectedIndex;
}

9 个答案:

答案 0 :(得分:4)

当我遇到ViewState的问题时(我怀疑你的情况)我使用它将数据恢复到动态填充的下拉对象

    public void Page_Load(object sender, EventArgs e){
            if (!IsPostBack)
            {
                Databind();
            }
            else {
                LoadAllViewStates();
            }
    }
    private void Databind()
        {
            DataTable questionnaireDT = null;
            DataTable questionsDT = null;
            DataTable indicatorDT = null;

            DataView tempView = QuestionnaireDS.Select(DataSourceSelectArguments.Empty) as DataView;
            questionnaireDT = tempView.Table;
            ViewState["QuestionnaireDL"] = questionnaireDT;
            QuestionnaireDL.DataSource = ViewState["QuestionnaireDL"];
            QuestionnaireDL.DataBind();

            tempView = QuestionDS.Select(DataSourceSelectArguments.Empty) as DataView;
            questionsDT = tempView.Table;
            ViewState["QuestionList"] = questionsDT;
            QuestionList.DataSource = ViewState["QuestionList"];
            QuestionList.DataBind();

            tempView = IndicatorDS.Select(DataSourceSelectArguments.Empty) as DataView;
            indicatorDT = tempView.Table;
            ViewState["IndicatorLst"] = indicatorDT;
            IndicatorLst.DataSource = ViewState["IndicatorLst"];
            IndicatorLst.DataBind();
        }

        private void LoadAllViewStates()
        {
            QuestionnaireDL.DataSource = ViewState["QuestionnaireDL"];
            QuestionnaireDL.DataBind();

            QuestionList.DataSource = ViewState["QuestionList"];
            QuestionList.DataBind();

            IndicatorLst.DataSource = ViewState["IndicatorLst"];
            IndicatorLst.DataBind();
        }

要恢复所选索引,我将selectedIndex传递给隐藏字段。

希望这有帮助吗?

顺便说一下,为什么要将DropDownList对象作为参数传递?而是调用无参数函数并在函数中填充DropDownList对象。

另外,请确保ViewState未关闭。

答案 1 :(得分:1)

这对你有用。但是,我有点困惑为什么你将下拉列表传递给函数来获取状态。你有多个下拉列表需要填写吗?我认为我们需要看到你的HTML更有帮助。

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
        GetStatesForDdl(ddl);
}

 private void GetStatesForDdl(DropDownList ddlStateList)
 {
     AppInputFormProcessor getStates = new AppInputFormProcessor();
     ArrayList States = new ArrayList();
     States = getStates.GetStates();
     ddlStateList.DataSource = States;
     ddlStateList.DataBind();
 }

答案 2 :(得分:1)

在您的示例中,您尝试从会话变量中获取所选值,但是没有显示实际在会话中设置任何内容的代码。

即使您有某种设置会话变量的异步调用,这也是一种非常危险的做法:只要有人打开第二个选项卡,就有可能导致数据损坏。

答案 3 :(得分:0)

首先,您需要仅在if( !IsPostBack ) { ...语句中填充和数据化列表。

下一步 - 永远不会填充Session [“ddlState”],不确定要填充它的位置,但是您可以按照所述更改所选索引。如果你没有在回发上调用DataBind(),这应该可以工作。

答案 4 :(得分:0)

这个怎么样:

protected void GetStatesForDdl(DropDownList ddlStateList)
{
    //remove event handler
    ddlStateList.SelectedIndexChanged -= new EventHandler(ddlState_SelectedIndexChanged);

    //business as usual
    AppInputFormProcessor getStates = new AppInputFormProcessor();
    ArrayList States = new ArrayList();
    States = getStates.GetStates();
    ddlStateList.DataSource = States;
    ddlStateList.DataBind();

    // then force it to select desired index
    ddlStateList.SelectedIndex = (int)Session["ddlState"];

   //ok, stick it back to control
   ddlStateList.SelectedIndexChanged += new EventHandler(ddlState_SelectedIndexChanged);
}

我建议在ViewState中使用局部变量而不是Session和SelectedValue而不是SelectedIndex。

答案 5 :(得分:0)

这可以帮到你:

绑定下拉列表时,请指定DataTextField和DataValueField属性。在提交期间将所选索引设置为0的原因是因为下拉列表不包含与其中每个项目关联的唯一值。请记住,DataValueField中指定的属性应该是唯一的。即,下拉列表中的每个项目都应该是唯一可识别的。

例如,考虑States类是这样指定的:

public class State
{
    public string Name { get; set; }
    public string Id { get; set; }
}

现在下拉列表应绑定,如下所示。对于每个州项目,“Id”属性是唯一的。

ddlStateList.DataSource = States;
ddlStateList.DataTextField = "Name";
ddlStateList.DataValueField = "Id";
ddlStateList.DataBind();

答案 6 :(得分:0)

如果禁用了ViewState,则必须将SelectedIndex保存到Session和Page_Load中,始终重新加载数据并直接设置索引。绑定数据源时,将索引作为参数发送到默认索引(来自会话),并在调用DataBind()后将SelectedIndex设置为此数字。

答案 7 :(得分:0)

当您说,您不使用ViewState时,是否意味着您已将该页面或下拉列表禁用?那可能是你的问题。我知道有很多人问你这个问题,但是我没有看到你的任何答案,建议你是否使用viewstate。当您的用户进行选择并且页面回发时,您仍然需要查看状态,因此您的页面即使在回发后也知道用户选择的内容。然后它由你来保存在session或viewstate中。

另一方面,如果您的视图状态已启用,请在新页面上添加一段代码,以查看问题何时开始显示。请记住不要触摸viewstate并使用默认值。首先,添加一个带有下拉列表和按钮的页面,并将其绑定到2个虚拟值,并在回发后读取用户选择。随着您不断添加更多代码和控件,如果问题再次出现,您将能够找到让您感到悲痛的代码行。

希望这有帮助。

答案 8 :(得分:0)

如果绑定OnInit中的下拉列表项,框架将自动处理所有视图状态。如果您在Page_Load中绑定它,则直到已经应用了viewstate之后才会添加它们。将其移至OnInit,您无需担心。