ASP.NET la case à cocher ne déclenche pas l'événement CheckedChanged lorsque vous décochez

J'ai une case à cocher sur un ASP.NET forme de contenu comme ceci:

<asp:CheckBox runat="server" ID="chkTest" AutoPostBack="true" OnCheckedChanged="chkTest_CheckedChanged" />

Dans mon code derrière j'ai la méthode suivante:

protected void chkTest_CheckedChanged(object sender, EventArgs e)
{
}

Lorsque je charge la page dans le navigateur et clique sur la case à cocher, elle est cochée, la page revient et je peux voir chkTest_CheckedChanged être appelé.

Lorsque je clique à nouveau sur la case à cocher, elle devient décochée, la page revient, mais chkTest_CheckedChanged n'est pas appelée.

Le processus est répétable, donc une fois la case décochée, la vérification déclenche le événement.

J'ai l'État de vue désactivé sur le Web.Config, l'activation de L'État de la vue provoque la disparition de ce problème. Que puis-je faire pour avoir un déclenchement d'événement fiable pendant que l'État de la vue reste désactivé?

Mise à Jour: Si je mets Checked="true" sur la balise serveur, la situation devient inversée avec le déclenchement de l'événement lors de la décochation de la case à cocher, mais pas l'inverse.

Mise à Jour 2: J'ai remplacé OnLoadComplete dans ma page et à partir de là, je peux confirmer que Request.Form["__EVENTTARGET"] est défini correctement à l'ID de ma case à cocher.

26
demandé sur Matt 2010-08-11 13:46:41

9 réponses

Implémenter une case à cocher personnalisée qui stocke la propriété Checked dans ControlState plutôt que {[3] } résoudra probablement ce problème, même si la case à cocher a AutoPostBack=false

Contrairement à ViewState, ControlState ne peut pas être désactivé et peut être utilisé pour stocker des données essentielles au comportement du contrôle.

Je n'ai pas d'environnement visual studio pour le moment à tester, mais cela devrait ressembler à ceci:

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);
            }
        }
    }
}

Plus d'infos ici.

18
répondu Johnny5 2011-08-10 01:21:47

Pour déclencher l'événement CheckedChanged définissez les propriétés suivantes pour la case à cocher, la propriété AutoPostBack doit être true et doit avoir une valeur par défaut cochée false ou true.

AutoPostBack="true" Checked="false"
20
répondu Able Alias 2017-05-12 09:25:16

Il ne se déclenche pas car avec viewstate désactivé, le code du serveur ne sait pas que la case à cocher a déjà été cochée, donc il ne sait pas que l'État a changé. En ce qui concerne asp.net sait que le contrôle checkbox a été décoché avant la publication et est toujours décoché. Cela explique également le comportement inverse que vous voyez lorsque vous définissez Checked="true".

7
répondu joshb 2011-08-05 03:38:07

C'est un ancien post mais j'ai dû partager ma solution simple afin d'aider les autres qui ont cherché ce problème.

La solution est simple: Activez AutoPostBack.

        <asp:CheckBox id="checkbox1" runat="server"
                AutoPostBack="True" //<<<<------
                Text="checkbox"
                OnCheckedChanged="knowJobCBOX_CheckedChanged"/>
7
répondu c0ldsh3ll 2014-09-10 22:49:57

Je ne suis pas sûr mais je suppose que ma solution ne fonctionne que pour. NET Framework 4.0:

Utilisez ViewStateMode = "Disabled" pour désactiver l'état de la vue au lieu de EnableViewState="false". Cela mettra en garde contre le même comportement, sauf que vous pouvez enregistrer un État de vue local.

Donc, sur votre case, définissez l'attribut ViewStateMode = "Enabled" et le problème est résolu, sans l'application d'une coutume case.

6
répondu Cristian Nicoleta 2012-03-27 11:47:23

Je voulais ranger un peu les choses, donc je viens de passer un peu de temps à tester une solution pour cela.

Joshb a raison avec son explication de la raison pour laquelle la case à cocher se comporte comme elle le fait.

Comme je ne sais pas comment j'ai fait l'année dernière ou même si je l'ai fait (je ne me souviens pas de ce sur quoi je travaillais à l'époque pour vérifier), j'ai mis en place une solution/solution de contournement 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 vous enregistrez maintenant CheckBox2 dans votre page et l'utilisez à la place de vos cases à cocher standard, vous l'événement CheckedChanged sera déclenché comme prévu avec ViewState désactivé et AutoPostBack activé.

La façon dont cela fonctionne permet à la case à cocher normale de faire son truc avec la validation et la vérification des modifications, mais effectue ensuite une vérification supplémentaire pour voir si c'était la cible de l'événement qui a causé la publication. S'il s'agissait de la cible, il renvoie true pour indiquer au framework de déclencher L'événement CheckedChanged.

Modifier: Veuillez noter que cela ne résout le problème que pour AutoPostBack sur la case à cocher. Si la publication est invoquée à partir d'autre chose (un bouton, par exemple), L'événement CheckedChanged présente toujours le problème observé.

1
répondu Matt 2011-08-06 21:29:37

, j'ai eu le même problème. J'ai passé beaucoup de temps dessus et finalement l'ai résolu.

Dans mon cas, le Checkbox est désactivé par défaut:

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

Il s'avère que ViewState n'est pas chargé pour les contrôles désactivés ou invisibles. Donc, supprimez Enabled="false" ou Visible="false" et cela fonctionnera comme prévu. Et bien sûr ViewState ne devrait pas être désactivé.

0
répondu algreat 2014-02-18 21:00:05

De plus: Vérifiez les erreurs dans la console JavaScript .

J'ai connu le même problème décrit par OP, sauf que cela ne s'est produit que dans Safari (checkbox a bien fonctionné dans Chrome et Firefox). Lors de l'inspection de la console JavaScript, j'ai trouvé une erreur qui était lancée par un sélecteur jQuery mal formé.

Dans mon cas, j'avais {[2] } qui manquait une fermeture ]. Cela a jeté une erreur dans Safari mais, étonnamment, pas dans Chrome ni Firefox.

0
répondu Mr.Z 2015-12-22 19:24:16

La réponse super facile est de définir le ViewState pour ce contrôle.

Ajoutez simplement le EnableViewState="true" à la propriété AutoPostBack="true" dans la balise checkbox.

0
répondu Scott Hurst 2016-01-07 21:11:36