2010-08-11 27 views
25

tengo una casilla en un formulario de contenido ASP.NET, así:ASP.NET CheckBox no desencadenar el evento CheckedChanged cuando desmarcando

<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 marca, la página se devuelve y puedo ver que se llama al chkTest_CheckedChanged.

Cuando vuelva a hacer clic en la casilla de verificación se desactiva, la página se devuelve, sin embargo, chkTest_CheckedChanged no se llama.

El proceso es repetible, por lo que una vez que CheckBox esté desmarcado, al marcarlo se desencadenará el evento.

Tengo estado de vista deshabilitado en Web.Config, lo que permite que este problema desaparezca. ¿Qué puedo hacer para disparar un evento confiable mientras View State permanece desactivado?

Actualización: Si fijo Checked="true" en la etiqueta del servidor de la situación se invierte con el evento de disparar cuando desmarcar la casilla de verificación, pero no al revés.

Actualización 2: he anulado OnLoadComplete en mi página y desde dentro no puedo confirmar que Request.Form["__EVENTTARGET"] está ajustada correctamente a la ID de mi casilla de verificación.

+2

que me pasa a mí también, ¿por qué sucede? ¿Alguna información? cualquier luz al final de este túnel (¿eso no me va a atropellar)? – Ayyash

+0

te ayudará si puedes publicar el código de tu evento Page_Load – Waqas

+0

No hay nada en el evento Page_Load. Todo el código está en la publicación original. – Matt

Respuesta

17

La implementación de un CheckBox personalizado que almacena la propiedad Checked en ControlState en lugar de ViewState probablemente va a 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 utilizar para almacenar datos que es esencial para el comportamiento del control.

que no tienen una Environnement visual studio en este momento para poner a prueba, pero que en caso se parece a esto:

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.

+0

Esto no funcionó para mí. La solución de Matt abajo hace – Marcin

+0

Gracias esto funciona como magia. No puedo creer todo el tiempo que he estado trabajando en .Net. Nunca me he encontrado con este problema hasta ahora. Esto también funciona en las casillas de verificación creadas dinámicamente, solo regístrelas como instancias de "MyCheckBox" en lugar de las instaladas de manera estándar y listo. – pharophy

+0

Grande, gracias. Por qué las casillas de verificación no pueden funcionar de la caja, no lo sé. –

7

No se activa porque con viewstate desactivado, el código del servidor no sabe que la casilla de verificación se ha verificado previamente, por lo tanto, no se conoce el estado cambiado. En cuanto a asp.net sabe, el control de casilla de verificación no se ha marcado antes de la devolución de datos y aún no se ha marcado. Esto también explica el comportamiento inverso que ve al establecer Checked="true".

+0

Vuelvo a esto después de un año, así que no recuerdo exactamente cuáles eran mis pensamientos en ese momento, pero tiene razón, el ciclo de vida de la página causa este efecto. Creo que posiblemente estaba esperando eso porque el __EVENTTARGET se estableció en mi casilla de verificación que ASP.NET podría ser lo suficientemente inteligente como para darse cuenta de que había cambiado. – Matt

1

Quería arreglar las cosas un poco, así que acabo de pasar un poco de tiempo probando una solución para esto.

joshb es correcto con su explicación de por qué el CheckBox se comporta de la manera que lo hace.

Como no sé cómo me las arreglé este año pasado o incluso si lo hice (no recuerdo en qué estaba trabajando en ese momento para comprobarlo), he preparado una solución simple/alternativa .

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 se registra CheckBox2 en su página y lo utiliza en lugar de tus casillas de verificación estándar, recibirá el evento CheckedChanged despedido como se espera con ViewState discapacitados y AutoPostBack habilitado.

La forma en que esto funciona es permitir que el CheckBox normal haga su trabajo con la validación y la comprobación de cambios, pero luego realiza una comprobación adicional para ver si era el objetivo del evento que causó la devolución. Si era el objetivo, se vuelve verdadero para indicar al marco que active el evento CheckedChanged.

Editar: Tenga en cuenta que esto solo resuelve 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.

+0

Puede ser útil para el caso cuando LoadPostData no está llamando http://stackoverflow.com/questions/3211200/asp-net-custom-control-when-is-loadpostdata -llamado – sll

6

no estoy seguro, pero supongo que mi solución está trabajando sólo para .NET Framework 4.0:

Uso ViewStateMode = "Disabled" para desactivar el estado de vista de insted EnableViewState="false". Esto advertirá 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 solucione el problema, sin implementar una casilla de verificación personalizada.

14

Para activar el evento CheckedChanged establezca las siguientes propiedades para CheckBox, la propiedad AutoPostBack debe ser verdadera y debe tener un valor predeterminado que sea falso o verdadero.

AutoPostBack="true" Checked="false" 
0

Tuve el mismo problema. He pasado mucho tiempo y finalmente lo he resuelto.

En mi caso el Checkbox se desactivadas por defecto:

<asp:CheckBox ID="chkActive" runat="server" Enabled="false"/> 

Resulta ViewState no está cargado para los controles con discapacidad o invisibles. Así que elimine Enabled="false" o Visible="false" y funcionará como se esperaba. Y por supuesto ViewState no se debe deshabilitar.

6

Es una publicación anterior pero tuve que compartir mi solución simple para ayudar a otras personas que buscaron este problema.

La solución es simple: Active AutoPostBack.

 <asp:CheckBox id="checkbox1" runat="server" 
       AutoPostBack="True" //<<<<------ 
       Text="checkbox" 
       OnCheckedChanged="knowJobCBOX_CheckedChanged"/> 
0

Además: Compruebe si hay algún error en la consola de JavaScript.

Experimenté el mismo problema exacto descrito por OP, excepto que solo ocurrió en Safari (checkbox funcionó bien en Chrome y Firefox). Al inspeccionar la consola de JavaScript, encontré un error que estaba siendo lanzado por un selector jQuery mal formado.

En mi caso, tuve $('a[id*=lbView') que faltaba un cierre ]. Esto arrojó un error en Safari pero, sorprendentemente, no en Chrome ni en Firefox.

-1

La respuesta súper fácil es configurar el ViewState para ese control.

Simplemente agregue EnableViewState="true" a la propiedad AutoPostBack="true" en la etiqueta de casilla de verificación.

Cuestiones relacionadas