c# ASP.Net динамически заполняемый DropDownList теряет выбранный индекс на кнопку отправки

Я динамически заполняю раскрывающийся список всех 50 состояний из ArrayList на PageLoad. Когда пользователь выбирает кнопку отправки (событие btnSubmit_Click), свойство SelectedIndex элемента управления dropdownlist всегда равно 0, независимо от выбранного пользователем выбора.


добавлен дополнительный код для устранения неполадок. Получение -1 как из переменной сеанса (bbb), так и из ddlState.selectedindex (bbb).

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 ответов


когда у меня возникли проблемы с ViewState (это то, что я подозреваю в вашем случае) l использовал это для восстановления данных в динамически заполненный выпадающий объект

    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 не выключается.


в вашем примере вы пытаетесь получить выбранное значение из переменной сеанса, но нет кода, который фактически устанавливает что-либо в сеансе.

даже если у вас есть какой-то асинхронный вызов, который устанавливает переменную сеанса, это очень опасная практика: как только кто-то открывает 2-ю вкладку, вы рискуете повредить данные.


Это должно работать для вас. Тем не менее, я немного смущен, почему вы передаете раскрывающийся список функции для получения состояний. У вас есть несколько выпадающих списков для заполнения? Я думаю, нам нужно увидеть ваш 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();
 }

сначала вам нужно будет заполнить и databing список только в if( !IsPostBack ) { ... заявление.

Next-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, должно быть уникальным. т. е. каждый пункт в выпадающем списке должны быть однозначно identifiyable.

например, рассмотрим, что состояния класс указывается следующим образом:

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 в сеанс и на Page_Load, вы всегда перезагружаете данные и устанавливаете индекс напрямую. При привязке источника данных отправьте индекс в качестве параметра по умолчанию index (from session) и установите SelectedIndex на этот номер после вызова DataBind ().


когда вы говорите, что не используете ViewState, означает ли это, что он отключен для страницы или вашего выпадающего списка? Это может быть твоей проблемой. Я знаю, что многие люди спрашивали вас об этом, но я не вижу никакого ответа от вас, чтобы предположить, используете ли вы viewstate. Когда ваш пользователь делает выбор и ваша страница публикуется, вам все равно нужно viewstate, чтобы ваша страница знала, что пользователь выбирает даже после публикации. Затем его до вас, чтобы сохранить его в сеансе или viewstate.

с другой стороны, если ваш viewstate включен, добавьте один фрагмент кода на новую страницу, чтобы увидеть, когда проблема начинает появляться. Не забудьте не прикасаться к viewstate и идти с по умолчанию. Для начала добавьте страницу с раскрывающимся списком и кнопкой и привяжите ее к 2 фиктивным значениям и прочитайте выбор пользователя на post back. По мере того, как вы добавляете больше кода и элементов управления, если проблема снова появится, вы сможете узнать, какая строка кода дает вам горе.

надеюсь, что это помогает.


Если вы привязываете элементы выпадающего списка в OnInit, все состояние представления будет обрабатываться автоматически платформой. Если вы привязываете его в Page_Load, вы не добавляете их до тех пор, пока viewstate уже не будет применен. Переместите его в OnInit, и вам не придется беспокоиться об этом.