Выбор ListBox не отображается после автопостбэка

Я знаю, что это не первый раз, когда здесь публикуется вопрос по этой проблеме, но мне не удалось найти ответ на свой вопрос.

У меня есть несколько ListBoxes на моей странице:

<tr>
    <td class="loqhArea2Area">
        <asp:ListBox ID="ListBox1Val1" class="InputItem" runat="server" AutoPostBack="true"></asp:ListBox>
    </td>
    <td class="loqhArea3Area">
        <asp:ListBox ID="ListBox2Val1" class="InputItem" runat="server" AutoPostBack="true"></asp:ListBox>
    </td>
    <td class="loqhArea4Area">
        <asp:ListBox ID="ListBox3Val1" class="InputItem" runat="server"></asp:ListBox>
    </td>
</tr>

Эти поля связаны друг с другом в некотором смысле, выбор в первом поле используется для заполнения второго и так далее четвертого. Чтобы получить от них информацию, я использую этот фрагмент кода:

protected override void OnInit(EventArgs e)
{
// Do some other stuff ...

    if (!IsPostBack)
    {
        // Fill the boxes on initial load
    }
    else
    {
        // INeedTheData takes an ID-string (in this case "Val1")
        // and the selected indexes as ints
        INeedTheData("Val1",
                      ListBox1Val1.SelectedIndex,
                      ListBox2Val1.SelectedIndex,
                      ListBox3Val1.SelectedIndex);

    }
    // Some error handling    
}

Проблема в том, что все SelectedIndexes возвращают -1, что, очевидно, не то, что мне нужно.

Я гуглил как сумасшедший в поисках решения этой проблемы. Все подсказки или зацепки приветствуются. Заранее спасибо!

Обновление: Может быть, это кому-то поможет, мой предшественник (с которым я, к сожалению, не смог связаться) реализовал этот довольно странный код, который действительно работает. Или я должен сказать вроде работает. Дело в том, что нам нужен был какой-то более надежный код, поэтому я решил его переписать.

INeedTheData("Val1"
    , Request.Form.AllKeys.Contains("ctl01$ListBox1Val1") ? Request.Form["ctl01$ListBox1Val1"] == string.Empty ? 0 : int.Parse(Request.Form["ctl01$ListBox1Val1"]) : 0
    , Request.Form.AllKeys.Contains("ctl01$ListBox2Val1") ? Request.Form["ctl01$ListBox2Val1"] == string.Empty ? 0 : int.Parse(Request.Form["ctl01$ListBox2Val1"]) : 0
    , Request.Form.AllKeys.Contains("ctl01$ListBox3Val1") ? Request.Form["ctl01$ListBox3Val1"] == string.Empty ? 0 : int.Parse(Request.Form["ctl01$ListBox3Val1"]) : 0);

Это решение нежелательно, поскольку оно получает данные с использованием жестко закодированных идентификаторов html, которые могут быть изменены при перестроении и реорганизации материала на странице в будущем. Во всяком случае, я подумал, что это должно быть введено здесь, так как это причина, по которой я его переписываю.

Как сказано выше, все комментарии приветствуются! Спасибо!

Обновление 2 (ответ @Deeptechtons): желаемое поведение У меня есть группа из трех ListBox, используемых для навигации и выбора из древовидного графа. Первое поле (ListBox1Val1) заполняется непосредственно из базы данных. Второй (ListBox2Val1) пуст, пока пользователь не выбрал свой выбор в первом. Это приводит к тому, что дочерние элементы выбранного узла в первом списке загружаются во второй. То же самое относится и к списку номер три (ListBox3Val1). Выберите узел во втором поле, и третье поле будет заполнено.


person dotmartin    schedule 06.04.2011    source источник
comment
Почему вы делаете это в OnInit, а не в PageLoad?   -  person Lazarus    schedule 06.04.2011
comment
Я не знаю на самом деле. Честно говоря, я новичок в проекте, а также в разработке asp.net. Я постараюсь переместить код!   -  person dotmartin    schedule 06.04.2011
comment
@Lazarus: это дает такое же поведение. :(   -  person dotmartin    schedule 06.04.2011
comment
@Lazarus @dotmartin Не могли бы вы включить состояние просмотра в этом списке, а затем перестроить проект и протестировать. <asp:ListBox ID="ListBox1Val1" class="InputItem" runat="server" EnableViewState="True" AutoPostBack="true"></asp:ListBox>   -  person Deeptechtons    schedule 07.04.2011
comment
@Deeptechtons: К сожалению, проблема остается.   -  person dotmartin    schedule 07.04.2011
comment
@dotmartin Это то, что вы делаете, выбранный индекс Listbox изменен, обратная передача selectedindex, с выбранным индексом listbox2 и выбранным индексом listbox3. Если да, тогда listbox2 selected index = -1, если ничего не выбрано. как в примере 1   -  person Deeptechtons    schedule 07.04.2011
comment
@Deeptechtons: я обновил вопрос, добавив описание желаемого поведения, но не совсем уверен, что это отвечает на ваш вопрос! Пожалуйста, вернись ко мне, если это не так..   -  person dotmartin    schedule 07.04.2011
comment
@dotmartin, не могли бы вы опубликовать код привязки данных, где вы выполняете Listboxval1.DataBind(). Находятся ли они внутри панели обновления с дочерними элементами в качестве триггеров, установленными как истинные.   -  person Deeptechtons    schedule 07.04.2011
comment
@Deeptechtons Да, дело в том, что это настолько плохо написанный код, что я ничего не могу понять. Я испробовал все приемы в своем арсенале, я думаю, что это нужно переписать сверху вниз. Я склоняюсь к тому, чтобы сдаться и опубликовать новый тикет для полного изменения дизайна во время нашего следующего спринта. Любые комментарии о том, как бы вы решили это?   -  person dotmartin    schedule 07.04.2011
comment
@dotmartin Через несколько минут я опубликую рабочий код с файлами aspx и cs.   -  person Deeptechtons    schedule 07.04.2011
comment
@Deeptechtons С нетерпением жду этого!   -  person dotmartin    schedule 07.04.2011
comment
@dotmartin, пожалуйста, посмотрите на код и попробуйте воспроизвести его.   -  person Deeptechtons    schedule 07.04.2011
comment
Я в деле @Deeptechtons!   -  person dotmartin    schedule 08.04.2011


Ответы (2)


@dotmartin Вот код, который вам нужен в файле Cs

 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ListBox1.DataSource = GetList();
            ListBox1.DataBind();
        }
    }

    protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        ListBox2.DataSource = GetSecondList(ListBox1.SelectedIndex);
        ListBox2.DataBind();
    }

    protected void ListBox2_SelectedIndexChanged(object sender, EventArgs e)
    {
        ListBox3.Items.Add(new ListItem(ListBox1.SelectedValue + "-" + ListBox2.SelectedValue, "Wippie"));
    }

    private ListItemCollection GetList()
    {
        ListItemCollection lstNumbers = new ListItemCollection();
        lstNumbers.Add(new ListItem("1", "One"));
        lstNumbers.Add(new ListItem("2", "Two"));
        lstNumbers.Add(new ListItem("3", "Three"));
        lstNumbers.Add(new ListItem("4", "Four"));
        lstNumbers.Add(new ListItem("5", "Five"));
        return lstNumbers;
    }

    private ListItemCollection GetSecondList(int iSelectedIndex)
    {
        ListItemCollection lstRandom = new ListItemCollection();
        System.Random RandNum = new System.Random();
        for (int i = 0; i < 10; i++)
        {
            lstRandom.Add(new ListItem(RandNum.Next(ListBox1.SelectedIndex, i + 1).ToString(), "random"));
        }
        return lstRandom;
    }

я только что сгенерировал несколько случайных чисел для привязки к списку.

Ниже приведен код файла aspx,

<form id="form1" runat="server">
        <asp:ScriptManager id="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <div>
            <asp:UpdatePanel id="UpdatePanel1" runat="server" updatemode="Conditional" childrenastriggers="true">
                <ContentTemplate>
                    <div>
                        <asp:ListBox id="ListBox1" autopostback="true" runat="server" onselectedindexchanged="ListBox1_SelectedIndexChanged"
                            width="200"></asp:ListBox></div>
                    <div>
                        <asp:ListBox id="ListBox2" autopostback="true" runat="server" onselectedindexchanged="ListBox2_SelectedIndexChanged"
                            width="200"></asp:ListBox></div>
                    <div>
                        <asp:ListBox id="ListBox3" autopostback="true" runat="server" width="200"></asp:ListBox>
                    </div>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
    </form>
person Deeptechtons    schedule 07.04.2011
comment
Работает как шарм. Спасибо за ваши большие усилия! Проблема с реализацией, которую мы использовали ранее, заключалась в том, что код был просто нечитаемым и недостаточно структурированным. Ваш пример многое проясняет. Еще раз спасибо, что выручили меня! Очень признателен. - person dotmartin; 08.04.2011
comment
@dotmartin Добро пожаловать! сложите сюда свои вопросы, когда доберетесь до конца дороги ;D - person Deeptechtons; 08.04.2011

Фактически, в ASP.NET управляющие события происходят после загрузки страницы в жизненном цикле страницы: Обзор жизненного цикла страницы ASP.NET.

Я предполагаю (но не уверен в точном названии), что в раскрывающемся списке должно быть событие SelectedIndexChanged, где вы должны подумать о новом выборе.

Надеюсь, это поможет!

person Tengiz    schedule 07.04.2011
comment
Спасибо за совет. Интересная ссылка, помогла мне понять многие вещи, которые меня интересовали в процессе жизненного цикла страницы. - person dotmartin; 08.04.2011