ASP.NET динамически добавляется LinkButton - не вызывается обработчик OnClick - PullRequest
2 голосов
/ 13 мая 2009

Я добавляю элемент управления LinkButton динамически в PlaceHolder. Если я добавлю новый экземпляр LinkButton в каждый OnInit (), то обработчик OnClick для этого LinkButton будет работать.

Однако, если я сохраню экземпляр LinkButton в сеансе, а затем добавлю его в коллекцию элементов управления PlaceHolder, LinkButton.OnClick не сможет сработать.

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

Так же, как примечание - это унаследованное приложение в 1.1, которое я только что перенес на 3.5. «Сломанный» подход, похоже, сработал в 1.1.

Спасибо за все ответы.

public static void Clicked(object sender, EventArgs e) {
    Debugger.Break();
}

protected override void OnPreInit(EventArgs e) {
    base.OnPreInit(e);
    InitLinkButton();
}

private void InitLinkButton() {    
    var lb = new LinkButton();
    plOne.Controls.Add(lb);
    lb.ID = "lb";
    lb.Text = "I will work.";
    lb.Click += Clicked;
    plOne.Controls.Add(lb);

    LinkButton lb2 = null;
    if (Session["lb2"] == null) {
        lb2 = new LinkButton();
        lb2.ID = "lb2";
        lb2.Text = "I won't work.";
        lb2.Click += Clicked;
        Session["lb2"] = lb2;
    } else {
        lb2 = (LinkButton)Session["lb2"];
    }
    plOne.Controls.Add(lb2);
}

Ответы [ 4 ]

10 голосов
/ 13 мая 2009

Пара вещей:

1) Никогда, никогда, никогда не сохраняйте экземпляр WebControl в Session. Каждый WebControl имеет ссылку на объект Page, который, конечно, ссылается на любой другой WebControl. Как только вы прячете WebControl в Session, вы в основном сохраняете всю страницу и все, что она содержит. Вы на шоссе в город утечки памяти.

2) Каждый элемент управления воссоздается при каждой обратной передаче. Я думаю, вы, возможно, думаете, что повторное создание кнопок LinkButton происходит медленно, но это не так.

3) Почему не воссоздание динамических элементов управления при обратной передаче? Это то, что вы должны делать с динамическими элементами управления. Идея заключается в том, что вы настраиваете страницу так же, как и раньше, так что ViewState может быть автоматически подключен к вашим элементам управления на основе их идентификаторов. Если вы попытаетесь динамически добавить элементы управления на свою страницу в любом месте после Init (), вы не сможете использовать ViewState для обработки ваших управляющих данных и должны будете реализовать собственный механизм.

Я рекомендую воссоздать ваши динамические элементы управления в Init () - это лучшая практика.

3 голосов
/ 13 мая 2009

Чтобы ответить на ваш вопрос, как заставить работать OnClick, вам нужно подключить событие к методу;

lb2.Click += new EventHandler(Clicked);

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

1 голос
/ 13 мая 2009

Действительно ужасная идея хранить LinkButton в сессии. Я даже не могу себе представить проблемы, которые могут вызвать. По крайней мере, LinkButton имеет ссылку (посредством обработчика Clicked) на страницу, которая на самом деле больше не должна существовать (страница была обработана и отправлена ​​клиенту). Но ссылка сохранит его, так что он не будет скопирован.

Как говорится, возможно , что вам просто нужно перемонтировать обработчик Clicked:

if (Session["lb2"] == null) {
    /* ... */
} else {
    lb2 = (LinkButton)Session["lb2"];
    lb2.Click += Clicked;
}

Поскольку событие LinkButton.Click связано с другим экземпляром класса Page (тем, который использовался ранее), его запуск не будет иметь никакого эффекта visible (так как эта страница был уже оказан). Конечно, как я уже говорил выше, это просто сумасшествие, поэтому я не проверял это.

Если вы используете это, то вам также следует отказаться от подписки на Page_PreRender или сделать что-то еще, чтобы избежать проблемы GC.

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

1 голос
/ 13 мая 2009

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

...