visual texto tamaño studio propiedades modificar letra como change cambiar agrandar c# .net asp.net user-controls controls

texto - label c# propiedades



¿Por qué los hijos de mi control de usuario personalizado no se están inicializando? (5)

¿Está configurando HRef en el método OnInit de la página? Si es así, intenta mover la asignación a Page_Load.

Los controles inician desde el más externo al más interno. Esto significa que si asigna el valor en OnInit de la página, los controles aún no se han inicializado.

Aquí hay un documento decente en el ciclo de vida de la página: http://www.codeproject.com/KB/aspnet/lifecycle.aspx

ACTUALIZACIÓN: He estado experimentando con mis controles un poco más y creo que me he acercado. Por favor, sigue leyendo para obtener información actualizada.

Tengo 2 controles de usuario de ASP.NET 2.0, uno de los cuales se coloca dentro del otro. Dentro del control interno tengo un control de etiqueta HtmlAnchor cual intento establecer una URL desde el control externo. Cuando intento establecer la propiedad HRef desde el marcado de la página de representación, el control HtmlAnchor es null y arroja una excepción.

La propiedad del set URL se llama antes del evento OnInit del control interno o externo y antes del evento '' OnPreInit '' de la página principal. Supongo que esto se debe a que estoy estableciendo el URL del control secundario en el marcado del control principal en la página en la que estoy renderizando los controles, lo que significa que el valor se establece antes de OnInit() . Aquí está la versión (reducida) del código que estoy usando:

[ParseChildren(true)]// <- Setting this to false makes the // page render without an exception // but ignores anything in the markup. [PersistChildren(false)] public partial class OuterControl : System.Web.UI.UserControl { // The private ''_Inner'' control is declared // in the .ascx markup of the control [PersistenceMode(PersistenceMode.InnerProperty)] public InnerControl Inner { get{ return _Inner; } set{ _Inner = value; } } } public partial class InnerControl : System.Web.UI.UserControl { // The private ''linkHref'' control is declared // in the .ascx markup of the control public string Url { get { return linkHref.HRef; } set { linkHref.HRef = value; } } }

El OuterControl se usa en mi página Default.aspx de esta manera:

<uc1:OuterControl ID="OuterCtrl1" runat="server"> <Inner Url="#" /> </uc1:OuterControl>

En el ejemplo de marcado anterior, si intento linkHref esta página, se lanza una excepción porque el control linkHref es nulo. Utilizando mi depurador puedo ver que cada control dentro de InnerControl es nulo, pero el evento OnInit() InnerControl & OuterControl aún no se ha activado cuando se accede a la propiedad Url .

ACTUALIZAR
Pensé que agregar los atributos '' ParseChildren '' y '' PersistChildren '' ayudaría. Los he usado en Controles de Servidor antes pero nunca en los Controles de Usuario, aunque el efecto parece ser similar. No creo que esté interpretando correctamente la documentación de estas dos propiedades, pero puede evitar que se produzcan excepciones. Sin embargo, el marcado de la página se ignora.

¿Alguien sabe una manera de tener este trabajo? No entiendo por qué estos controles obtienen valores establecidos antes de OnInit() . Cuando intento establecer sus valores utilizando el marcado ASPX, el constructor para el InnerControl se llama dos veces. Una vez para establecer los valores basados ​​en el marcado (supongo) y nuevamente en OnInit() (que supongo que es el motivo por el que los valores de marcado se ignoran).

¿Es este esfuerzo inútil o me estoy acercando desde el ángulo equivocado?


Tu dijiste:

// The private ''linkHref'' control is declared // in the .ascx markup of the control

¿Cambia algo si haces esto un control protegido?


El árbol de control se construye después de Init (); de hecho, Init () es el lugar para agregar sus controles al árbol, antes de que se deserialice viewstate. No puede acceder a linkHref antes de que se haya construido el árbol de control.

Una posible solución es almacenar la URL hasta que pueda usarla. Dentro del control interno, cambie la propiedad URL a una cadena simple:

public string Url { get; set; }

En el controlador de eventos Load o PreRender del control interno, propague la cadena al objeto linkHref (ahora inicializado):

linkHref.HRef = value;


Saludos Dan,

Me enfrenté a un problema similar antes con el desorden de controles anidados, así que me encontré con ganas de ayudar, y lo marqué como favorito porque me gustó.

Reproduje el problema de la siguiente manera:

Creado un control de usuario llamado Inner:

Inner.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Inner.ascx.cs" Inherits="Inner" %> <a runat="server" id="linkHref">I''m inner</a>

Inner.ascx.cs

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class Inner : System.Web.UI.UserControl { public string Url { get { return this.linkHref.HRef; } set { this.linkHref.HRef = value; } } }

Creado un control de usuario llamado Outer:

Outer.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Outer.ascx.cs" Inherits="Outer" %> <%@ Register src="Inner.ascx" tagname="Inner" tagprefix="uc1" %> <uc1:Inner ID="_Inner" runat="server" />

Outer.ascx.cs

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class Outer : System.Web.UI.UserControl { [PersistenceMode(PersistenceMode.InnerProperty)] public Inner Inner { get { return this._Inner; } } }

Luego creó una página llamada Default:

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register src="Outer.ascx" tagname="Outer" tagprefix="uc1" %> <%@ Reference Control="~/Inner.ascx" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <uc1:Outer ID="Outer1" runat="server"> <Inner Url="http://google.com" /> </uc1:Outer> </div> </form> </body> </html>

Con todo esto, la página "predeterminada" funciona bien.

Lo que me parece extraño en tu código es esta línea:

public InnerControl Inner { //... set{ _Inner = value; } }

¿De qué sirve crear un setter para el control interno? No puedo entenderlo se supone que la instancia de control interno se crea a partir del marcado en el control externo, y es esta instancia creada cuyo html anchor debe ser manipulado. Si agrego estas líneas a la propiedad interna en Outer.ascx.cs

set { this._Inner = (ASP.inner_ascx)value; }

Obtendré una excepción de referencia nula como en el caso original. Creo que el colocador da instrucciones al generador de páginas ASP.Net para que cree otra instancia de control interno y lo configure usando la propiedad interna. No estoy seguro, pero si tiene tiempo, puede saber exactamente cómo sucede al examinar los archivos cs generados por el creador de la página, que residen en los archivos ASP.Net temporales.


Si OuterControl.ascx se ve como

<%@ Register TagPrefix="uc1" TagName="InnerControl" Src="InnerControl.ascx" %> <uc1:InnerControl runat="server" ID="_Inner" />

entonces el problema es que la propiedad OuterControl.Inner tiene un acceso de set . Elimine el acceso del set para solucionar el problema:

[PersistenceMode(PersistenceMode.InnerProperty)] public InnerControl Inner { get { return _Inner; } }

Explicación: Si OuterControl.Inner tiene un acceso de set ...

  1. Primero, ASP.NET ejemplifica ASP.outercontrol_ascx (la clase generada dinámicamente que deriva de OuterControl ), que a su vez ASP.innercontrol_ascx una instancia de ASP.innercontrol_ascx (la clase generada dinámicamente que deriva de InnerControl ).
  2. A continuación, como la propiedad Inner tiene un acceso de set , ASP.NET crea una nueva instancia de InnerControl ( no ASP.innercontrol_ascx , como era de esperar) e intenta inicializar su propiedad Url a "#" . Por supuesto, esto arroja NullReferenceException porque linkHref es creado por ASP.innercontrol_ascx , no por InnerControl .
  3. Finalmente (si no se ha lanzado una excepción), ASP.NET establece Inner a la instancia de InnerControl que creó en el paso 2.

Si OuterControl.Inner no tiene un OuterControl.Inner set , en el paso 2, ASP.NET simplemente establece OuterCtrl1.Inner.Url en "#" , y el paso 3 se omite.

Nota: Un par de otras respuestas indican que los controles se crean o inicializan en Init . Esto es incorrecto; los controles declarados en marcado se crean y se inicializan muy temprano en el ciclo de vida de la página, en FrameworkInitialize (que ocurre antes de PreInit ).