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

#c# #asp.net #.net #controls

Вопрос:

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

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

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

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

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

Ответ №1:

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

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

Ответ №2:

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

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

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

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

Ответ №3:

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

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

Ответ №4:

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

Ответ №5:

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

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

 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;
}
 

Ответ №6:

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