asp.net - valido - viewstate[]
ASP.NET CheckBox no activa el evento CheckedChanged cuando se desmarca (9)
Además: compruebe si hay errores en la consola de JavaScript .
Experimenté el mismo problema exacto descrito por OP, excepto que solo sucedió en Safari (la checkbox
funcionó bien en Chrome y Firefox). Al inspeccionar la consola de JavaScript, encontré un error que estaba siendo lanzado por un selector jQuery
formato incorrecto.
En mi caso, tuve $(''a[id*=lbView'')
que faltaba un cierre ]
. Esto arrojó un error en Safari pero, sorprendentemente, ni en Chrome ni en Firefox.
Tengo un CheckBox en un formulario de contenido ASP.NET así:
<asp:CheckBox runat="server" ID="chkTest" AutoPostBack="true" OnCheckedChanged="chkTest_CheckedChanged" />
En mi código detrás tengo el siguiente método:
protected void chkTest_CheckedChanged(object sender, EventArgs e)
{
}
Cuando cargo la página en el navegador y hago clic en la casilla de verificación, se chkTest_CheckedChanged
, la página se publica de nuevo y puedo ver que se llama a chkTest_CheckedChanged
.
Cuando vuelvo a hacer clic en el CheckBox, se desmarca, la página se publica de nuevo, sin embargo, no se llama a chkTest_CheckedChanged
.
El proceso es repetible, por lo que una vez que el CheckBox no está marcado, la verificación activará el evento.
Tengo View State inhabilitado en Web.Config, habilitando View State hace que este problema desaparezca. ¿Qué puedo hacer para que se dispare un evento confiable mientras el estado de vista permanece deshabilitado?
Actualización: si configuro Checked="true"
en la etiqueta del servidor, la situación se invierte con el evento que se activa cuando se desmarca CheckBox, pero no al revés.
Actualización 2: He anulado OnLoadComplete
en mi página y desde allí puedo confirmar que Request.Form["__EVENTTARGET"]
está configurado correctamente en el ID de mi CheckBox.
Es una publicación antigua, pero tuve que compartir mi solución simple para ayudar a otros que buscaron este problema.
La solución es simple: encienda AutoPostBack.
<asp:CheckBox id="checkbox1" runat="server"
AutoPostBack="True" //<<<<------
Text="checkbox"
OnCheckedChanged="knowJobCBOX_CheckedChanged"/>
La implementación de un CheckBox personalizado que almacena la propiedad Checked
en ControlState
en lugar de ViewState
probablemente resolverá ese problema, incluso si la casilla de verificación tiene AutoPostBack=false
A diferencia de ViewState, ControlState no se puede desactivar y se puede usar para almacenar datos que son esenciales para el comportamiento del control.
No tengo un entorno de estudio visual en este momento para probar, pero debería tener este aspecto:
public class MyCheckBox : CheckBox
{
private bool _checked;
public override bool Checked { get { return _checked; } set { _checked = value; } }
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//You must tell the page that you use ControlState.
Page.RegisterRequiresControlState(this);
}
protected override object SaveControlState()
{
//You save the base''s control state, and add your property.
object obj = base.SaveControlState();
return new Pair (obj, _checked);
}
protected override void LoadControlState(object state)
{
if (state != null)
{
//Take the property back.
Pair p = state as Pair;
if (p != null)
{
base.LoadControlState(p.First);
_checked = (bool)p.Second;
}
else
{
base.LoadControlState(state);
}
}
}
}
Más información here .
La respuesta súper fácil es configurar ViewState
para ese control.
Simplemente agregue EnableViewState="true"
a la propiedad AutoPostBack="true"
en la etiqueta de la casilla de verificación.
No estoy seguro, pero supongo que mi solución funciona solo para .NET Framework 4.0:
Use ViewStateMode = "Disabled"
para deshabilitar el estado de vista EnableViewState="false"
de EnableViewState="false"
. Esto evitará el mismo comportamiento, excepto que puede guardar un estado de vista local.
Por lo tanto, en su casilla de verificación, establezca el atributo ViewStateMode = "Enabled"
y el problema se solucionará, sin implementar una casilla de verificación personalizada.
No se dispara porque con el estado de vista deshabilitado, el código del servidor no sabe que la casilla de verificación se había marcado previamente, por lo tanto, no sabe que el estado cambió. Por lo que asp.net sabe, el control de la casilla de verificación estaba desactivado antes de la devolución de datos y todavía está desactivado. Esto también explica el comportamiento inverso que se ve al configurar Checked="true"
.
Para activar el evento CheckedChanged, establezca las siguientes propiedades para CheckBox, la propiedad AutoPostBack debe ser verdadera y debe tener un valor predeterminado ya sea falso o verdadero.
AutoPostBack="true" Checked="false"
Quería ordenar las cosas un poco, así que he pasado un poco de tiempo probando una solución para esto.
joshb está en lo cierto con su explicación de por qué el CheckBox se comporta como lo hace.
Como no sé cómo me recuperé el año pasado o incluso si lo hice (no recuerdo en qué estaba trabajando en el momento de la verificación), he reunido una solución / solución simple.
public class CheckBox2 : CheckBox
{
protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
bool isEventTarget = postCollection["__EVENTTARGET"] == UniqueID;
bool hasChanged = base.LoadPostData(postDataKey, postCollection);
hasChanged = hasChanged || isEventTarget;
return hasChanged;
}
}
Si ahora registra CheckBox2 en su página y lo utiliza en lugar de sus CheckBoxes estándar, recibirá el evento CheckedChanged como se espera con ViewState deshabilitado y AutoPostBack habilitado.
La forma en que funciona es permitir que el CheckBox normal haga su trabajo con la validación y la verificación de cambios, pero luego realiza una verificación adicional para ver si fue el objetivo del evento que causó la devolución. Si era el objetivo, devuelve true para indicar al marco que genere el evento CheckedChanged.
Edición: tenga en cuenta que esto solo soluciona el problema de AutoPostBack en el CheckBox. Si el PostBack se invoca desde cualquier otra cosa (un botón, por ejemplo), el evento CheckedChanged aún muestra el problema observado.
Yo tuve el mismo problema. He pasado mucho tiempo en él y finalmente lo he resuelto.
En mi caso, la Checkbox
fue desactivada por defecto:
<asp:CheckBox ID="chkActive" runat="server" Enabled="false"/>
A su vez, ViewState
no está cargado para controles deshabilitados o invisibles. Entonces elimine Enabled="false"
o Visible="false"
y funcionará como se espera. Y, por supuesto, ViewState
no debería estar deshabilitado.