Динамически добавленный EventBandler ListBox не запускается на ASP.Net - PullRequest
0 голосов
/ 20 ноября 2010

Прежде всего, извините, если мой вопрос может быть дублирован, но я слишком много искал и не могу найти решение. У меня есть UserControl. Этот пользовательский элемент управления создаст динамически ListBox, если заданный счетчик List> 0. Элементы управления добавляются динамически, нет проблем с их добавлением, но обработчик событий не добавляет. Если я выберу элемент в первом listBox, второйListBox будет добавлен динамически, и элементы также будут добавлены динамически. Сначала появляется listBox, но обработчик события selectedIndexChanged не работает. В чем может быть проблема с моим кодом?

РЕДАКТИРОВАТЬ: Я пытался добавить

li.Attributes.Add("onselectedindexchanged","selectedIndexChanged");

или

li.AutoPostBack = true;

но все еще не стреляет ...

private List<string> myList = new List<string>() { "Serkan", "Kadir" };
    private List<string> mySecondList = new List<string>() { "Istanbul", "Ankara" };

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            if (myList.Count > 0)
            {
                ListBox li = new ListBox();
                li.ID = Guid.NewGuid().ToString();
                li.SelectedIndexChanged += new EventHandler(this.selectedIndexChanged);
                foreach (string item in myList)
                {
                    li.Items.Add(item);
                }

                this.Controls.Add(li);
            }
        }
    }

    private void selectedIndexChanged(object sender, EventArgs e)
    {
        ListBox li2 = new ListBox();
        li2.ID = Guid.NewGuid().ToString();

        foreach (string item in mySecondList)
        {
            li2.Items.Add(item);
        }
        this.Controls.Add(li2);
    }

Ответы [ 4 ]

0 голосов
/ 22 ноября 2010

Ребята, мой код работает хорошо.Я только что попробовал это в diff Visual Studio сегодня, и все работало нормально.@ RichardW1001 и @Microgen спасибо за ваш интерес и сообщения.

0 голосов
/ 21 ноября 2010

Причина, по которой ваши события не происходят, заключается в том, что вы неправильно понимаете жизненный цикл страницы ASP.Net. Когда вы запрашиваете страницу, ASP.Net создает новый экземпляр соответствующего класса страницы. Этот экземпляр ничего не знает ни о каких других экземплярах, которые были созданы в прошлом. Он использует экземпляр класса Page для генерации набора HTML, который он отправляет обратно в браузер в качестве ответа. Затем этот экземпляр класса Page на сервере уничтожается вместе с его состоянием.

Когда страница отправляется обратно, ASP.Net считывает данные с использованием viewstate, идентификаторов и т. Д. И сопоставляет отправленные обратно элементы HTML с серверными элементами управления в только что созданном экземпляре страницы. Элементы, добавленные в коллекцию Controls предыдущего экземпляра, не существуют в этом новом экземпляре, поэтому ASP.Net не может их распознать или инициировать события на них.

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

http://www.codeproject.com/KB/aspnet/MultiNestMDGridview.aspx

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

Edit -

Если вы измените событие Page_Init, как предлагает @Microgen, удалите if (! Page.IsPostBack), установите AutoPostBack = true и используйте энергонезависимый идентификатор для динамически добавляемого элемента управления, это вызовет событие на стороне сервера. и визуализировать 2-й список. Он не будет работать с Guid.New (), потому что коллекция Controls на вновь созданной странице не будет содержать ничего с соответствующим ID, поэтому обработчик событий не будет подключен. Это ответило бы на вопрос, как первоначально отправлено. Однако ваш 2-й список не будет запускать события, если вы не создадите его и не добавите его в Page.Controls в Page_Init таким же образом и т. Д. Для 3-го и т. Д., Все по причине, описанной выше.

0 голосов
/ 21 ноября 2010

1 - динамически добавлять элементы управления должны быть загружены в событие page_init не в page_load Списки с 2 флажками не работают с .attributes.add ("selectedindexchanged", "..."), поскольку список флажков является элементом управления asp.net, но он отображает в html как обычный ввод

0 голосов
/ 20 ноября 2010
li.Attributes.Add("onselectedindexchanged","selectedIndexChanged"); 

Добавляет атрибут HTML на стороне клиента. Метод selectedIndexChanged, который вы здесь показали, является методом на стороне сервера. Вам нужно либо добавить авто-постбэк к своему элементу управления и обработчик событий на стороне сервера, чтобы он вызывал вашу функцию C # на сервере, либо создать функцию JavaScript на стороне клиента для обработки на стороне клиента. событие.

редактировать ---

Когда страница отправляется обратно на сервер, элемент управления перестает существовать. Страница является новой версией, в которой список элементов управления не добавлен. Событие вызывается, когда автоматическая обратная передача имеет значение true, но элемент управления не существует в объекте Page сервера, и если вы удаляете блок If Page.IsPostBack, элемент управления создается заново, поэтому элемент управления не тот, чье событие было возбуждено, и этот контроль все еще не существует.

Какова реальная цель этого контроля? Это просто для обеспечения мастер-детали?

редактировать 2 ---

Созданное для вас решение, которое работает:

Страница:

<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true" Visible="false" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"></asp:ListBox>
<br />
<asp:ListBox ID="ListBox2" runat="server" Visible="false"></asp:ListBox>

Codebehind:

private List<string> myList = new List<string> {
    "Serkan",
    "Kadir"
};
private List<string> mySecondList = new List<string> {
    "Istanbul",
    "Ankara"

};
protected void Page_Load(object sender, System.EventArgs e)
{
    if (!Page.IsPostBack) {
        if (myList.Count > 0) {
            ListBox1.DataSource = myList;
            ListBox1.DataBind();
            ListBox1.Visible = true;
        }
    }
}

protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    ListBox2.DataSource = mySecondList;
    ListBox2.DataBind();

    ListBox2.Visible = true;
}
...