2008-11-21 11 views
9

Tengo este problema con TextBox creado dinámicamente.Controlador de eventos no activado para controles creados dinámicamente

Cuando TextBox se crea en PageLoad, se activa su evento TextChanged.
Pero cuando eliminé dinámicamente y recreé el TextBox, el TextChanged no se activó.

Este es el código:

archivo .aspx

<body> 
    <form id="form1" runat="server"> 
    <div> 

    <asp:Table ID="Table1" runat="server"> 
     <asp:TableRow> 
     <asp:TableCell ColumnSpan="2">Fixed content</asp:TableCell> 
     </asp:TableRow> 
    </asp:Table> 
    </form> 
</body> 

.cs presentar

public partial class test : System.Web.UI.Page 
{ 
    string myText = "a"; 

    protected void Page_Load(object sender, EventArgs e) 
    { 
    WriteRows(); 
    } 

    private void WriteRows() 
    { 
    TableRow tr = new TableRow(); 

    TableCell tc = new TableCell(); 
    TextBox txt = new TextBox(); 
    txt.Text = myText; 
    txt.TextChanged += new EventHandler(txt_TextChanged); // Assign event handler 
    tc.Controls.Add(txt); 
    tr.Controls.Add(tc); 

    tc = new TableCell(); 
    tc.Text = txt.Text; 
    tr.Controls.Add(tc); 

    Table1.Controls.AddAt(1, tr); 
    } 

    private void txt_TextChanged(object sender, EventArgs e) 
    { 
    myText = ((TextBox)sender).Text; 
    RedrawTable(); // Delete the row (incl. the TextBox) and rewrite it 
    } 

    private void RedrawTable() 
    { 
    Table1.Controls.RemoveAt(1); 
    WriteRows(); 
    } 
} 

¿Alguien tiene una solución para que el evento se dispara siempre?

+0

¿Ha resuelto su problema? Tengo el mismo problema con el botón asp creado dinámicamente. Establecí ID en el botón, sin embargo, esto no da ningún resultado. – Nurlan

Respuesta

11

manejo de eventos se realiza mediante ASP.NET, haciendo coincidir el ID del control de & los parámetros de la petición. En su caso, el TextBox creado durante txtTextChanged() tendrá una identificación automática porque no especifica ningún ID explícito. Esa ID se publicará nuevamente durante el evento de cambio de texto.

Después del evento de carga de página, ASP.NET intentará encontrar un control con dicha ID para activar el evento. Obviamente, ASP.NET no podrá encontrar la coincidencia porque el TextBox creado durante Page_Load() es diferente y tendría una ID diferente.

Para solucionar esto: especificar un ID explícita para su cuadro de texto:

TextBox txt = new TextBox(); 
txt.Text = myText; 
txt.ID = "txtBox"; 
+0

+1 Creo que esta es la única diferencia entre mis controles creados dinámicamente y los especificados en este snippit de código. Hago algo como esto: 'txt.ID = String.Format (" txtUserId_ {0} ", id)' –

+0

@BryanRehbein M también asigna la ID también pero el evento aún no se activa, m en .net 2.0 framework – 1Mayur

+0

Tengo el mismo problema con el botón asp creado dinámicamente. Establecí ID en el botón, sin embargo, esto no da ningún resultado. – Nurlan

1

Tuve un problema similar. Creo que el problema es que los controles creados dinámicamente no se mantienen en estado de visualización y no sobreviven a una devolución de datos. Aquí hay un comentario extraído de mi código que describe la solución que se me ocurrió (puede que no sea la única, pero funcionó para mí).

Esta página se utiliza para definir una cuadrícula dinámicamente. El usuario hace clic en las casillas de verificación para indicar qué campos incluir en la grilla. La lógica de esta página hace que dos cosas esenciales:

(1) Mantiene el objeto GridDefinition que se mantiene en ViewState. (2) Reconstruye los controles agregados programáticamente (esencialmente todo en el objeto de tabla) de GridDefinition en ViewState en cada devolución de datos. Los controles añadidos dinámicamente NO se vuelven a crear en la devolución de datos desde ViewState. De hecho, descubrí que si no recreas los controles, sus eventos no se dispararán. Al parecer :

 "The process that matches controls to posted values occurs 
     after page_load completes, so it has to occur just like this 
     if you are to use this way." 

Cuando llego a un evento de control que indica algún cambio en los datos, que tienen que reflejar que el cambio en el objeto GridDefinition almacenada en ViewState. De esta forma, en la devolución de datos NEXT , el control se puede recrear correctamente (por ejemplo, un cuadro de texto que indica el texto del encabezado para una columna de cuadrícula).

0

Cuando estaba investigando este problema, era en el contexto de los menús dinámicos, y hay un montón de respuestas de Google que, juntas, me ayudaron a superarlo (porque es un requisito bastante común, supongo). No tiene un resumen de la respuesta, pero podría ser un lugar útil para comenzar (es decir, google for Dynamic Menus .NET). Hay varias preguntas aquí en este sitio también.

0

... como otra sugerencia, ¿no son los eventos vinculantes después de la carga de Page_Load demasiado tarde? y por lo tanto, no serán despedidos en la devolución. tal vez algo para ver ..

+0

En mi código asp.net, puedo vincular eventos a controles creados dinámicamente a lo largo de Page_Load, Page_LoadComplete es demasiado tarde y los eventos enlazados no se activarán. –

2

para un evento de devolución al fuego, el control que debe desencadenar el evento debe estar disponible con el mismo id y los mismos datos en el ciclo de vida de devolución de datos.

Si tiene controles estáticos (definidos en su aspx/ascx/master) y viewstate encendidos, entonces se recrearán automágicamente.

Si no desea utilizar estado de vista, o utilizar controles dinámicos, es necesario DataBind controles en cada Page_Load, por lo que los controles están en marcha en el tiempo para los eventos al fuego (que sucede después de Load)

si cambia el ID de un control principal, o una página, podría accidentalmente descartar el autobus de viewstate, ya que los ID de control contienen ID de ancestros. Creo que deberías estar seguro haciendo eso, siempre y cuando lo hagas en Page_Init (antes de que viewstate esté configurado)

0

Me recuerda una vez más por qué evito asp - para mí parece un nivel de abstracción demasiado . Pero por analogía con javascript, ¿es posible que termines con más de un controlador en el evento?

3

intente crear los controles en el método Page_Init() ...

2

controles volver a crear dinámicamente creados en Page_Init. No tendrá acceso a los datos de viewstate de un control si lo vuelve a crear en Page_Load (viewstate se carga en PreLoad, lo que ocurre antes de Page_Load).

Además, no olvide asignar una ID al control.

0

Su respuesta dada a continuación con el código completo:

string myText = "a"; 

protected void Page_Load(object sender, EventArgs e) 
{ 
    WriteRows(); 
} 

private void WriteRows() 
{ 
    TableRow tr = new TableRow(); 

    TableCell tc = new TableCell(); 
    TextBox txt = new TextBox(); 
    txt.Text = myText; 

    txt.ID = "txt1"; 

    txt.TextChanged += new EventHandler(txt_TextChanged); // Assign event handler 

    txt.AutoPostBack = true; 

    tc.Controls.Add(txt); 
    tr.Controls.Add(tc); 

    tc = new TableCell(); 
    tc.Text = txt.Text; 
    tr.Controls.Add(tc); 

    Table1.Controls.AddAt(0,tr); 

} 

private void txt_TextChanged(object sender, EventArgs e) 
{ 
    myText = ((TextBox)sender).Text; 
    RedrawTable(); // Delete the row (incl. the TextBox) and rewrite it 
} 

private void RedrawTable() 
{ 
    Table1.Controls.RemoveAt(0); 
    WriteRows(); 
} 
0

Se le requerirá a simplemente asignar una propiedad ID con el cuadro de texto. Debería resolver tu problema.

0

Tuve el mismo problema, y ​​en mi caso txt.AutoPostBack = verdadero fue lo que me perdí. El valor predeterminado es falso, fácil de olvidar.

Cuestiones relacionadas