Жизненный цикл страницы — использование FindControl для ссылки на элемент управления, созданный программно во время загрузки страницы.

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

Я поместил инструкцию FindControl в метод загрузки страницы после кода, который их создает, но получаю ошибку:

Ссылка на объект не указывает на экземпляр объекта.

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

Может ли кто-нибудь посоветовать, где в моем коде мне нужно разместить инструкцию FindControl, чтобы она могла найти эти программно созданные текстовые поля?


person Jay Wilde    schedule 10.10.2008    source источник


Ответы (6)


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

Вот пример рекурсивной реализации FindControl: Recursive Page.FindControl. Вы можете найти много других примеров, погуглив «рекурсивный findcontrol».

person Daniel Auger    schedule 10.10.2008

Если вы создаете текстовые поля программно, вы можете напрямую использовать их для управления ими. Нет необходимости в FindControl (который также будет медленнее)

TextBox txt = new TextBox();
...
txt.Text = "Text";

Если вам нужен доступ к другим методам, вы можете просто сделать txt частной переменной класса.

Если вам действительно нужно использовать FindControl - добавляются ли текстовые поля на страницу (добавляются в список элементов управления страницы) при вызове функции?

person rslite    schedule 10.10.2008

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

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

person Samuel Kim    schedule 10.10.2008

Если вы добавляете текстовые поля в CreateChildControls, вам, возможно, придется вызвать SureChildControls перед доступом к ним.

person Cristian Libardo    schedule 10.10.2008

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

Если вы поместите это в класс, вам нужно будет получить ссылку на элемент управления, например:

Dim imgStep2PreviewIcon As Image = Eyespike.Utilities.FindControl(Of Control)(Page, "imgStep1PreviewIcon")
imgStep2PreviewIcon.Visible = False

Код VB.NET

Public Shadows Function FindControl(ByVal id As String) As Control
    Return FindControl(Of Control)(Page, id)
End Function

Public Shared Shadows Function FindControl(Of T As Control)(ByVal startingControl As Control, ByVal id As String) As T
    Dim found As Control = startingControl
    If (String.IsNullOrEmpty(id) OrElse (found Is Nothing)) Then Return CType(Nothing, T)
    If String.Compare(id, found.ID) = 0 Then Return found
    For Each ctl As Control In startingControl.Controls
        found = FindControl(Of Control)(ctl, id)
        If (found IsNot Nothing) Then Return found
    Next
    Return CType(Nothing, T)
End Function

C# (не тестировалось, создано с использованием converter.telerik.com)

public new Control FindControl(string id)
{
    return FindControl<Control>(Page, id);
}

public static new T FindControl<T>(Control startingControl, string id) where T : Control
{
    Control found = startingControl;
    if ((string.IsNullOrEmpty(id) || (found == null))) return (T)null; 
    if (string.Compare(id, found.ID) == 0) return found; 
    foreach (Control ctl in startingControl.Controls) {
        found = FindControl<Control>(ctl, id);
        if ((found != null)) return found; 
    }
    return (T)null;
}
person Brian Boatright    schedule 26.10.2008

Если вы сделаете свои элементы управления TextBox во время переопределения OnInit (до вызова base.OnInit(e), я полагаю), они будут доступны во время Page.OnLoad и любых связанных событий. Вы также помещаете их в граф объекта ViewState в правильном положении, что бесценно для работы с обратными сообщениями и особенно с проверкой на стороне сервера.

person cfeduke    schedule 10.10.2008