tag route page net for dinamicamente crear controles asp asp.net dynamic user-controls postback

asp.net - route - select asp-for asp-items



Control de usuario creado dinĂ¡micamente que no puede manejar eventos en PostBack (9)

Tengo un control de usuario que se carga dinámicamente en la página utilizando el siguiente código en Init de la página.

Dim oCtl As Object oCtl = LoadControl("~/Controls/UserControl1.ascx") oCtl.Id = "UserControl11" PlaceHolder1.Controls.Clear() PlaceHolder1.Controls.Add(oCtl)

El control del usuario también contiene un botón y no puedo capturar el clic del botón dentro del control del usuario.


Aquí está el código completo de la página

Partial Class DynamicLoad Inherits System.Web.UI.Page Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init If IsPostBack Then If Not (Session("ctl") Is Nothing) Then Dim oCtl As Object oCtl = Session("ctl") PlaceHolder1.Controls.Add(oCtl) End If End If End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Dim oCtl As Object oCtl = LoadControl("~/Controls/UserControl1.ascx") oCtl.Id = "UserControl11" PlaceHolder1.Controls.Clear() PlaceHolder1.Controls.Add(oCtl) Session("ctl") = oCtl End If End Sub End Class

Aquí está el código completo para el usuario Control

Partial Class UserControl1 Inherits System.Web.UI.UserControl Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Label1.Text = "This is Text AFTER Post Back in User Control 1" End Sub End Class


Asegúrese de cargar el control en cada devolución: si el control no está en el árbol de controles cuando la página se publica, ASP.NET no generará el evento de clic de botón.


Como me lo preguntaste, escribiría tu evento init así. Dejaré el evento Load como un ejercicio:

Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init If IsPostBack AndAlso Session("ctl") IsNot Nothing Then Dim MyControl As Control = Session("ctl") PlaceHolder1.Controls.Add(MyControl) End If End Sub

También encontraría un nombre mejor que "mycontrol", pero como no sé lo que hace el control, esto tendrá que hacer.


Debe asegurarse de que el control exista en la página antes de que .NET ingrese el paso "Manejo de eventos de postback" del ciclo de vida de la página. Como el control se agrega dinámicamente, debes asegurarte de que en cada publicación posterior recreas ese control para que pueda encontrar el control para disparar el evento.


Desea cargar solo el control cuando no isPostBack


No lo sé sin intentarlo, pero ¿qué ocurre si programáticamente cableas el controlador de eventos del botón? Por ejemplo, en el código subyacente para el Control de Usuario mismo, en Init o Load (no seguro):

AddHandler Button1.Click, AddressOf Button1_Click

Si eso no hace nada, sé que es menos eficiente, pero ¿qué pasa si no almacena la instancia de Control de usuario en la sesión y siempre la recrea en Page_Init cada vez?


Unas cuantas preguntas:

  1. ¿En qué punto del ciclo de vida de la página cargan el control?
  2. ¿Dónde está el código del controlador de eventos? ¿En el control mismo o intentas conectarlo a la página?
  3. ¿Qué has hecho hasta ahora para conectar el evento?

Finalmente, las pautas de estilo para .Net específicamente recomiendan no usar ninguna verriga de prefijos de Hugarian como o en oCtl, y debe escribirla como control en lugar de como objeto.


Hay un par de cosas que estás haciendo que no son necesarias y probablemente causen tus problemas.

Estos son:

  1. No es necesario almacenar el objeto de control en la sesión. El Control mismo debería usar ViewState y Session State para almacenar información según sea necesario, no la instancia completa.
  2. No deberías estar revisando PostBack al crear el control. Debe crearse cada vez para permitir que ViewState funcione y que el evento esté conectado.
  3. Los controles cargados después de cargar ViewState a menudo tienen problemas para funcionar correctamente, así que evite cargarlos durante el evento Carga de página siempre que sea posible.

Este código funciona para mí:

Default.aspx

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Test_User_Control._Default" %> <!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"> <asp:PlaceHolder ID="PlaceHolder1" runat="server" /> </form> </body> </html>

Default.aspx.vb

Partial Public Class _Default Inherits System.Web.UI.Page Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init Dim control As Control = LoadControl("~/UserControl1.ascx") PlaceHolder1.Controls.Add(control) End Sub End Class

UserControl1.ascx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UserControl1.ascx.vb" Inherits="Test_User_Control.UserControl1" %> <asp:Label ID="Label1" Text="Before Button Press" runat="server" /> <asp:Button ID="Button1" Text="Push me" runat="server" />

UserControl1.ascx.vb

Public Partial Class UserControl1 Inherits System.Web.UI.UserControl Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Label1.Text = "The button has been pressed!" End Sub End Class


Acabo de experimentar un problema similar al tuyo, excepto que en mi caso no usé una sesión para almacenar el control.

En mi caso, localicé el problema en esta línea:

PlaceHolder1.Controls.Clear()

Lo que hice fue crear controles secundarios y los agregué al contenedor primario en Page_Init, luego procesé algunos controladores de eventos y luego en Page_PreRender recreé toda la lista nuevamente con los datos actualizados.

La solución que utilicé en este caso fue crear la colección de control una vez: en la fase inicial del ciclo de página.