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

У меня есть страница 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. в последней строке кода.

EDIT:

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

Ответы [ 4 ]

6 голосов
/ 26 июля 2011

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

UserControl UC_text = (UserControl)this.NamingContainer.FindControl("text1");
2 голосов
/ 27 июля 2011

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

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-подобных селекторов» (оно может находить элементы независимо от того, где они находятся в иерархии). У кого-нибудь есть лучшее решение?

2 голосов
/ 26 июля 2011

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

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

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

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

0 голосов
/ 21 марта 2017

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

пример:

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

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

((UpdatePanel)showbutton1.FindControl("UpdatePanel1")).Update();
...