Asp.net Usercontrol LoadControl Проблема - PullRequest
       9

Asp.net Usercontrol LoadControl Проблема

15 голосов
/ 27 октября 2008

У меня проблема при использовании LoadControl( type, Params ). Позвольте мне объяснить ...

У меня супер простой пользовательский элемент управления (ascx)

<%@ Control Language="C#" AutoEventWireup="True" Inherits="ErrorDisplay" Codebehind="ErrorDisplay.ascx.cs" EnableViewState="false" %>

<asp:Label runat="server" ID="lblTitle" />
<asp:Label runat="server" ID="lblDescription" />

с кодом (c #) позади:

public partial class ErrorDisplay : System.Web.UI.UserControl
{

    private Message _ErrorMessage;    

    public ErrorDisplay()
    {
    }

    public ErrorDisplay(Message ErrorMessage)
    {
        _ErrorMessage = ErrorMessage;
    }    

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (_ErrorMessage != null)
        {
            lblTitle.Text = _ErrorMessage.Message;
            lblDescription.Text = _ErrorMessage.Description;
        }
    }
}

В другом месте моего веб-приложения я добавляю экземпляр usercontrol на страницу, используя следующий код:

divValidationIssues.Controls.Add(LoadControl(typeof(ErrorDisplay), new object[] { MessageDetails }));   

Я использую перегруженную версию LoadControl, потому что я хочу передать параметр Message конструктору. Все это , кажется работает нормально.

Однако, когда OnPreRender() запускается в пользовательском управлении ErrorDisplay, переменные lblTitle и lblDescription равны null, несмотря на то что они имеют эквивалент разметки. Переменная сообщения была правильно заполнена.

Может кто-нибудь пролить свет на то, почему это может происходить?

Спасибо

EDIT:

Просто для ясности добавлю, что код, который программно добавляет пользовательский контроль на страницу, запускается в ответ на нажатие кнопки, поэтому «страница хостинга» проходила через Init, Page_Load и теперь обрабатывает событие обработчики.

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

Ответы [ 6 ]

21 голосов
/ 27 октября 2008

Я также попробовал следующий код - который дает одинаковый результат (т. Е. И lblTitle, и lblDescription равны нулю)

protected void Page_Load(object sender, EventArgs e)
{
    if (_ErrorMessage != null)
    {
        lblTitle.Text = _ErrorMessage.Message;
        lblDescription.Text = _ErrorMessage.Description;
    }
}

У меня было понимание, что функция LoadControl привела элемент управления, который она загружает, к текущему «состоянию» страницы, на которую она включена. следовательно, Init, Page_Load и т. д. все выполняются как часть вызова LoadControl.

Интересно, что эта (оставшаяся без ответа) запись на форуме asp.net демонстрирует ту же проблему, что и я.

MSDN Форумы Сообщение

Дополнительно - из MSDN:

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

Следовательно, не должен ли LoadControl правильно инициализировать элемент управления?

EDIT:

Хорошо, я отвечаю на свой вопрос здесь.

Я нашел ответ на пост форума, на который я ссылался выше Здесь

По сути, ответ таков: LoadControl( type, params ) не может вывести ascx 'page infront' для анализа и, следовательно, не беспокоит инициализацию какого-либо из элементов управления. Когда вы используете версию LoadControl( "ascx path" ), ей присваивается страница в начале и, следовательно, выполняется весь анализ и инициализация.

Итак, в общем, мне нужно изменить код, инициирующий управление, и разделить его на отдельные части. * 1034 Т.е. *

Control ErrorCntrl = LoadControl("ErrorDisplay.ascx");
ErrorCntrl.ID = SomeID;
(ErrorCntrl as ErrorDisplay).SetErrorMessage = MessageDetail;
divErrorContainer.Controls.Add(ErrorCntrl);

И все должно работать нормально. Это не так аккуратно, как моя предыдущая попытка, но по крайней мере это сработает.

Я все еще открыт для предложений по улучшению вышеупомянутого.

Приветствия

0 голосов
/ 20 апреля 2014

У меня была похожая проблема с событием DayRender элемента управления Calendar, в которой я хотел добавить пользовательский элемент управления в коллекцию e.Cell.Controls. После нескольких неудачных попыток, когда пользовательский элемент управления page_load не сработал или список элементов в ascx выдал пустое исключение, я обнаружил, что если я инициализирую свой элемент управления в форме с помощью LoadControl (ascx), а затем начинаю доступ к элементам разметки в ascx, все работало нормально. Этот подход вообще не зависит от события Page_Load на ascx.

ASCX разметка

код позади

Открытый класс CPCalendarCell Унаследован от System.Web.UI.UserControl

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

End Sub

Public Sub Add(txt As String)
    Dim li As New ListItem(txt, txt)
    lstDay.Items.Add(li)
End Sub

Конечный класс

страница ASPX разметка

код события Calendar DayRender в форме

Private Sub Calendar1_DayRender(sender As Object, e As System.Web.UI.WebControls.DayRenderEventArgs) Handles Calendar1.DayRender
    Dim div As CPCalendarCell = LoadControl("~/UserControls/CPCalendarCell.ascx")
    div.ID = "dv_" & e.Day.Date.ToShortDateString.Replace(" ", "_")

    **e.Cell.Controls.Add(div)**

    div.Add(e.Day.Date.Month.ToString & "/" & e.Day.Date.Day.ToString)
    div.Add("Item 1")
    div.Add("Item 2")
    e.Cell.Style.Add("background-color", IIf(e.Day.IsWeekend, "whitesmoke", "white").ToString)
End Sub
0 голосов
/ 26 ноября 2013

Здесь - это сообщение в блоге, написанное Стивеном Роббинсом. В посте объясняется, как передавать параметры для пользовательского элемента управления, используя LoadControl, аналогично тому, что будет делать LoadControl(Type, object[]), , за исключением того, что оно работает :)

0 голосов
/ 28 октября 2008

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

Рад, что вы нашли ответ на свой вопрос!

0 голосов
/ 27 октября 2008

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

0 голосов
/ 27 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...