Как найти пользовательский элемент управления страницы ASP.NET внутри события другого пользовательского элемента управления на этой странице ASP.NET РЕДАКТИРОВАТЬ: различные заполнители содержимого?

У меня есть страница ASP.NET с 2 зарегистрированными пользовательскими элементами управления. Первая имеет только одну кнопку. Второй - простой текст, скрытый по умолчанию. Я хочу, чтобы второй был видимым, когда нажата кнопка в первом (то есть при событии нажатия кнопки).

Страница ASP.NET:

<%@ Page Title="" Language="C#" CodeFile="test.aspx.cs" Inherits="test" %>
<%@ Register Src="~/UC_button.ascx" TagName="button" TagPrefix="UC" %>
<%@ Register Src="~/UC_text.ascx" TagName="text" TagPrefix="UC" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MyTestContent" Runat="Server">
    <UC:button ID="showbutton1" runat="server" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MyTestContent2" Runat="Server">
    <UC:text runat="server" Visible="false" ID="text1" />
</asp:Content>

UC_Button.ascx.cs:

protected void button1_Click(object sender, EventArgs e)
{
    Button btnSender = (Button)sender;
    Page parentPage = btnSender.Page;
    UserControl UC_text = (UserControl)parentPage.FindControl("text1");
    UC_text.Visible = true;
}

Что я делаю неправильно? Меня хорошо знают Object reference not set to an instance of an object. ошибка в этой последней строке кода.

РЕДАКТИРОВАТЬ:

Одна вещь, которую я забыл упомянуть при первой публикации этого. Пользовательские элементы управления находятся в разных <asp:Content></asp:Content> элементы управления (я редактировал верхний пример). Если я помещу их в один и тот же заполнитель, код будет работать нормально. Если я помещу их в отдельные заполнители контента, я никак не смогу найти их с помощью findcontrol. Почему это так и как я могу их найти?

4 ответа

Решение

Хорошо, я нашел решение, пока лучше не придет мой путь. Проблема в том, как указал Джейми Диксон (спасибо, Джейми):

The FindControl method does not do a deep search for controls. It looks directly in the location you specify for the control you're requesting.

Поэтому, поскольку у меня есть пользовательские элементы управления в разных заполнителях контента, я должен сначала найти целевой заполнитель (где находится пользовательский элемент управления), а затем я могу искать в нем пользовательский элемент управления:

protected void Dodaj_Feed_Panel_Click(object sender, EventArgs e)
    {
        ContentPlaceHolder MySecondContent = (ContentPlaceHolder)this.Parent.Parent.FindControl("MyTestContent2");

        UserControl UC_text = (UserControl)MySecondContent.FindControl("text1");
        UC_text.Visible = true;
    }

что действительно раздражает и смущает меня this.Parent.Parent отчасти потому, что я знаю, что это не лучшее решение (если я немного изменю иерархию, этот код сломается). На самом деле эта часть кода состоит в том, что она поднимается на два уровня вверх по иерархии страниц (то есть страницы, где находятся оба пользовательских элемента управления). Я не знаю какая разница с this.Page потому что для меня это означает то же самое, но не работает для меня.

Долгосрочное решение будет что-то вроде серверных "jQuery-подобных селекторов" (оно может находить элементы независимо от того, где они находятся в иерархии). У кого-нибудь есть лучшее решение?

Пожалуйста, проверьте ниже:

UserControl UC_text = (UserControl)this.NamingContainer.FindControl("text1");

Метод FindControl не выполняет глубокий поиск элементов управления. Он выглядит прямо в месте, указанном для запрашиваемого элемента управления.

В вашем случае вам нужно что-то вроде:

UserControl UC_text = (UserControl)Content1.FindControl("text1");

Вы также можете увидеть мой вопрос здесь: IEnumerable и Recursion с использованием yield return, который демонстрирует метод поиска глубоких элементов управления по типу.

Используйте идентификатор пользовательского элемента управления, затем поместите элементы управления (например, текстовое поле) в панель, затем попробуйте этот код с главной страницы.

пример:

TextBox txt = (TextBox)showbutton1.FindControl("Textbox1");

для обновления с помощью udpatepanel: TextBox txt = (TextBox)showbutton1.FindControl("Textbox1"); txt.Text="Hello World!";

((UpdatePanel)showbutton1.FindControl("UpdatePanel1")).Update();
Другие вопросы по тегам