繁体   English   中英

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

[英]c# ASP.Net Dynamically populated DropDownList loses selected index on submit button

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

当我遇到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未关闭。

这应该适合你。 但是,我有点困惑为什么你将下拉列表传递给函数来获取状态。 你有多个下拉列表需要填写吗? 我想我们需要看到你的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();
 }

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

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

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

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

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

这个怎么样:

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。

这可以帮助你:

绑定下拉列表时,请指定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();

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

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

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

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM