FindControl retorna null/nothing en una Content Page

Hoy me he encontrado esta cuestión en las NewsGroup de ASP.NET:

Tengo un control de usuario MiControl1.ascx con un boton con este código:

TextBox oTxt1 = (TextBox)this.Page.FindControl("TextBox1");

Asimismo hay 2 ASPXs: 

Pagina1.aspx que contiene el TextBox1 pero no tiene definida una MasterPage.

Pagina2.aspx que contiene el TextBox1 pero ahora si tiene definida una 
MasterPage. 

Pagina1.aspx y Pagina2.aspx tienen MiControl1.ascx. 

Cuando Pagina1.aspx funciona OK. Pero cuando hago lo mismo en la 
Pagina2.aspx, FindControl() falla.  

Dónde está el problema y cómo lo soluciono?

La verdad es que es una pregunta frecuente que suelo encontrarme y la solución está en la MSDN:

FindControl searches the current naming container for the specified server control.

Un naming container es cualquier control que implementa la interfaz INamingContainer. MasterPage y Content Controls implementan esta interfaz y por tanto son contenedores. La clave está en buscar el control en el contenedor adecuado, por tanto el método FindControl que se usa en el control de usuario busca sólo en el contenedor actual (La página) y como no utiliza recursividad para buscar el control entre toda la jerarquía de controles devuelve null o nothing.

La solución:

TextBox t;
 
if (Page.Master != null)
{
    foreach (Control control in Page.Master.Controls)
    {
        if (control is HtmlForm)
        {
            foreach (Control controlform in control.Controls)
            {
                if (controlform is ContentPlaceHolder)
                {
                    t = (TextBox)controlform.FindControl("TextBox1");
                    if (t != null)
                        break;
                }
            }
        }
    }
}
else
{
    t = (TextBox)Page.FindControl("TextBox1");
}

Si la página tiene MasterPage, buscamos en la colección de controles de la MasterPage el control Htmlform que contiene los ContentPlaceHolder y en ellos buscamos el TextBox1, sino directamente buscamos el control en la página.

Como véis la clave está en buscar el control en el contenedor correcto.

Salu2

Published 30/7/2007 10:29 por Luis Ruiz Pavón
Archivado en: ,,
Comparte este post:
http://geeks.ms/blogs/lruiz/archive/2007/07/30/findcontrol-retorna-null-nothing-en-una-masterpage.aspx

Comentarios

# re: FindControl retorna null/nothing en una Content Page

Gracias, justo lo que estaba buscando.

Saturday, January 26, 2008 4:26 PM por Fabricio

# re: FindControl retorna null/nothing en una Content Page

Justamente tenía este problema.

Para mejorar la funcionalidad de esto es mejor ponerlo sobre una página padre de todas del sistema y sobreescribir el FindControl de la pagina. Asi de esa forma no debemos ensuciar código en el resto de las páginas.

Thursday, September 11, 2008 8:15 PM por Matias

# re: FindControl retorna null/nothing en una Content Page

Una pregunta, tengo un ascx que está contenido en un aspx que tiene master page. El problema que tengo es que quiero hacer referencia desde el ascx a un control del aspx, y me marca error. Object reference not set to an instance of an object.

Que ámbito o contenedor debo de usar? ya probé this.findcontrol, page.parent.findcontrol, parent.page.findcontrol, y nada...

Gracias por la ayuda..

Thursday, October 09, 2008 5:31 PM por Eli Rodriguez

# re: FindControl retorna null/nothing en una Content Page

excelente el codigo, pero, funciona cuando el control esta contenido dentro de un update panel, no puedo ver el ejemplo que te marco

Monday, November 10, 2008 8:16 PM por marcos alvarez

# Gracias!!!

Gracias me funciono el codigo, tenia ese problema desde un par de dias

Tuesday, March 09, 2010 4:59 PM por Jaimito Pagina

# en una gridview template no funca

bueno yo tengo un gridview y utilizo el template de este control y pues lo he editado  para traerme la foto  el nombre y el id enuna cosulta y pues lo trae  normal pero tambien dentro de ese template tengo un button y kiero al hacer click en ese button kedarme con el valor de label que tiene el id ... para esto hago referencia para almacenarlo en una variable utilizando el findcontro y naa

este es el evento del button que esta dentro del template

Protected Sub Button4_Click(ByVal sender As Object, ByVal e As EventArgs)

       Me.MultiView1.ActiveViewIndex = 0

       Me.pnlFecha.Visible = True

       Dim x As String

       Dim myControl1 As Control = FindControl("Label7")

       If (Not myControl1 Is Nothing) Then

           ' Get control's parent.

           Dim myControl2 As Control = myControl1.Parent

           Response.Write("Parent of the text box is : " & myControl2.ID)

       Else

           Response.Write("Control not found.....")

       End If

   End Sub

nunca sale pues alguna sugerencia  puesto que el label7 que esta dentro del template  tiene el id  pues que quiero u saludo

Saturday, January 08, 2011 5:21 AM por maicol8k

# Tampoco funciona con un ASPxGridView

He probado el código con un ASPxGridView y tampoco funciona dentro de la plantilla EditForm tengo mi control y sigue saliendo Null

Tuesday, February 15, 2011 9:05 PM por Andres