Проблемы с жизненным циклом страницы в моем aspx

То, что я пытаюсь сделать, это генерировать Linkbuttons всякий раз, когда пользователь нажимает на статические LinkButtons, которые находятся внутри моего aspx, выглядит так:

Они выглядят так:

<asp:LinkButton ID="lnkSubWeb" runat="server" OnCommand="lbWeb_Click" />

Метод, который срабатывает, следующий:

/// <summary>
/// Handles the Click event of the lbWeb control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="CommandEventArgs"/> instance containing the event data.</param>
protected void lbWeb_Click(object sender, CommandEventArgs e)
{
    var url = e.CommandArgument.ToString();
    using (var site = new SPSite(url))
    {
        using (var selectedWeb = site.OpenWeb())
        {
            ViewState["RelativeUrl"] = selectedWeb.ServerRelativeUrl;
            ViewState["WebUrl"] = selectedWeb.Url;
            LoadWebItems(selectedWeb);
        }
    }
}

Насколько я знаю, цикл страницы работает следующим образом: Загрузка страницы -> Щелчок кнопки -> Предварительная визуализация страницы.

Итак, в основном, когда пользователь нажимает на эту кнопку ссылки, я хочу динамически генерировать 5 кнопок ссылок, а также добавлять и передавать им событие lbWeb_Click, но оно не срабатывает. Ничего не происходит, когда я нажимаю на сгенерированные LinkButtons.

Поэтому, когда я сохранил данные во ViewState, я использую следующий метод для создания этих кнопок ссылок:

private void Page_PreRender(object sender, EventArgs e)
{
    RelativeUrl = (string)ViewState["RelativeUrl"];
    WebUrl = (string)ViewState["WebUrl"];
    if (!string.IsNullOrEmpty(RelativeUrl))
    {
        LoadBreadCrumb(RelativeUrl, WebUrl);
    }
}

Метод LoadBreadCrumb() выглядит так:

private void LoadBreadCrumb(string relativeurl, string weburl)
{

    var relativePath = relativeurl.Substring(1);
    var urlList = weburl.ParseUrl();
    var linkList = new List<string>(relativePath.Split('/'));
    for (int i = 0; i < linkList.Count; i++)
    {
        var link = UppercaseFirst(linkList[i]);
        var linkButton = new LinkButton
        {
            Text = link + " > ",
            CssClass = "breadcrumb",
            CommandArgument = urlList[i]
        };
        linkButton.Command += lbWeb_Click;
        bcHolder.Controls.Add(linkButton);

    }

}

Таким образом, в основном этот код генерирует кнопки ссылок именно так, как я хочу, но lbWeb_Click не срабатывает на них.

С другой стороны, я пытался поместить этот код в Page_Load, и это не работает, всегда на один шаг позади. LinkButtons не отображаются после события щелчка, но он генерируется после Page_Load, а затем событие щелчка на них действительно работает.

Любая помощь приветствуется


person Obsivus    schedule 25.03.2014    source источник
comment
Пробовали ли вы использовать точки останова, чтобы увидеть, срабатывает ли что-нибудь или вам просто кажется, что ничего не происходит?   -  person Justin    schedule 26.03.2014
comment
Да, lbWeb_click не запускается.   -  person Obsivus    schedule 26.03.2014


Ответы (1)


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

Вы должны создавать все динамические элементы управления (т. е. вызывать LoadBreadCrumb) в контексте события PreInit. См. документацию по жизненному циклу страницы ASP.NET в MSDN.


Боковое примечание: то, как вы строите навигационную цепочку, немного неоптимально в отношении параметров построения пути URL в SharePoint. Вы должны принять во внимание, что существуют управляемые пути, которые не соответствуют какому-либо семейству сайтов (SPSite) напрямую, и что вдоль пути есть дочерние сайты (SPWeb вложенные в корневой веб-сайт SPSite). В настоящее время, вызывая new SPSite(url) с аргументом, который является либо управляемым путем, либо URL-адресом дочернего сайта, вы получите сразу включающее семейство сайтов, которое, в свою очередь, обозначает URL-адрес, отличный от того, что находится в url.

person Ondrej Tucny    schedule 25.03.2014
comment
Есть ли какое-нибудь решение для этого? Возможно ли убедиться, что lbWeb_Click запускается до загрузки страницы? Да, я знаю об этом, и для этого решения это работает. ParseUrl() — это специальный метод расширения, который исправляет это. - person Obsivus; 26.03.2014
comment
Круто, я попробую событие PreInit, это должно быть правильно? protected void Page_PreInit(отправитель объекта, EventArgs e) {//code} - person Obsivus; 26.03.2014
comment
Я попытался использовать PreInit, и теперь кажется, что Linkbuttons не генерируются. Это может быть из-за того, что PreInit выполняется до моего события click? - person Obsivus; 26.03.2014
comment
Конечно, он будет выполняться до вашего обработчика событий. В этом-то и дело! Вы не можете сначала выполнить обработчик события, который еще не был инициализирован. - person Ondrej Tucny; 26.03.2014
comment
Вам действительно следует прочитать учебник о жизненном цикле страницы ASP.NET и обработке обратных передач. - person Ondrej Tucny; 26.03.2014
comment
Хм, хорошо, я храню важные данные в состояниях просмотра с помощью обработчика событий щелчка, который мне нужно использовать при создании кнопок ссылок. - person Obsivus; 26.03.2014