por nombre example control buscar aspx c# .net asp.net findcontrol

c# - nombre - ASP.Net FindControl no funciona, ¿cómo es posible?



find control by id c# (7)

Aquí hay una referencia sobre cómo se denominan los controles de formulario web ...

Identificación de control de formularios web

He usado FindControl en el pasado, antes de .NET 2.0 / 3.0. Parece que ahora, por alguna razón, las ID de mis controles obtienen un nombre funky asignado. Por ejemplo, asigné un ID "cbSelect" a una casilla de verificación, pero FindControl no lo encuentra. Cuando veo el HTML se le asignó ctl00_bodyPlaceHolder_ctl02_cbSelect .

No he encontrado un ejemplo de FindControl que lo mencione. De hecho, todo el mundo parece usar el control de encontrar como normal.

Entonces, ¿estoy haciendo algo mal? ¿Cambió .Net? ¿Puede alguien arrojar algo de luz sobre esto para mí, es realmente frustrante?


Cuando busque un control en una colección de controles, use siempre la ID que le asignó al control, no la que ve en el procesamiento de publicación de origen. Si FindControl () no encuentra el control que sabe que existe, es muy probable que no esté buscando en la rama derecha de la jerarquía de control. Una función recursiva ha sido exitosa para mí.

Aquí está mi ejemplo de lo que uso para VB.NET 3.5:

Function FindControlRecursive(ByVal ctrl As Control, ByVal id As String) As Control Dim c As Control = Nothing If ctrl.ID = id Then c = ctrl Else For Each childCtrl In ctrl.Controls Dim resCtrl As Control = FindControlRecursive(childCtrl, id) If resCtrl IsNot Nothing Then c = resCtrl Next End If Return c End Function

Este es un ejemplo de cómo implementaría tópicamente esta función en mi clase de página base:

Dim form HtmlForm = CType(FindControlRecursive(Me, "Form"), HtmlForm)


Cuando está representando el html, ASP.NET prefijará todos los identificadores de control con los identificadores de los contenedores de nombres (Controles de usuario, etc.) en una jerarquía que se remonta hasta la raíz del documento. Esto asegura que todas las ID sean únicas para las devoluciones de publicaciones, etc.

Esto no afecta el uso de FindControl, donde debe usar la ID en el marcado original.


Este es el código VB.NET que me funcionó:

<Extension()> _ Function FindChildControlById(ByVal controlToStartWith As Control, ByVal controlIdToFind As String) As Control If controlToStartWith Is Nothing Then Return Nothing If controlToStartWith.ID = controlIdToFind Then Return controlToStartWith For Each childControl As Control In controlToStartWith.Controls Dim resCtrl As Control = FindChildControlById(childControl, controlIdToFind) If resCtrl IsNot Nothing Then Return resCtrl Next childControl Return Nothing End Function '' Function FindChildControlById(ByVal controlToStartWith As Control, ByVal controlIdToFind As String) As Control

El crédito es para George por el código inicial de VB.NET. Solo lo modifiqué un poco, con 2 cambios funcionales: el mío no da error si / cuando null / Nothing se pasa como control de entrada, y el mío se implementa como una Extensión. Mis otros 3 cambios menores no afectan la funcionalidad, pero para mí, fueron simplificaciones de código. Pero sé que es muy subjetivo.

Entonces este método puede ser usado con:

Dim c1 As Control = Page.FindChildControlById("aspControlID")

Y si desea convertirlo en una clase secundaria específica de un Control, así:

Dim c1 As Control = Page.FindChildControlById("aspControlID") Dim c As HyperLink = TryCast(c1, HyperLink)

Actualización: Mi función ahora se llama ''FindChildControlById'' (anteriormente era ''FindMiControl''). Me gustó más la sugerencia de SpeedNet.


He tenido bastante suerte al resolver este problema en "la mayoría" de los casos con un método de extensión simple

Puede llamarlo a cualquier control de contenedor de nivel superior que considere mejor, incluida la propia página si desea escanear toda la jerarquía de control.

public static Control FindAnyControl(this Page page, string controlId) { return FindControlRecursive(controlId, page.Form); } public static Control FindAnyControl(this UserControl control, string controlId) { return FindControlRecursive(controlId, control); } public static Control FindControlRecursive(string controlId, Control parent) { foreach (Control control in parent.Controls) { Control result = FindControlRecursive(controlId, control); if (result != null) { return result; } } return parent.FindControl(controlId); }


Podría escribir el extensor para encontrar cualquier control en la página usando la recursión. Esto podría estar en alguna clase de Util / Helper.

private static Control FindControlIterative(this Control control, string id) { Control ctl = control; LinkedList<Control> controls = new LinkedList<Control>(); while(ctl != null) { if(ctl.ID == id) { return ctl; } foreach(Control child in ctl.Controls) { if(child.ID == id) { return child; } if(child.HasControls()) { controls.AddLast(child); } } ctl = controls.First.Value; controls.Remove(ctl); } return null; }


Probablemente esté utilizando una MasterPage o controles de usuario (ascx) y esta es la razón por la que cambian los ID de cliente. Imagina que tienes un control en la página maestra con el mismo ID que uno en la página. Esto daría lugar a choques. Los cambios de id aseguran que todas las propiedades de ClientID sean únicas en una página.

FindControl necesita una atención especial cuando se trabaja con MasterPages. Echa un vistazo a ASP.NET 2.0 MasterPages y FindControl () . El FindControl funciona dentro de un contenedor de nombres . El MastePage y la página son diferentes contenedores de nombres.