web-dev-qa-db-fra.com

ASP. Les gestionnaires d'événements de bouton NET ne se déclenchent pas au premier clic, mais au deuxième clic après un PostBack

Contexte: Je personnalise une application existante ASP .NET/C #. Elle possède son propre petit "framework" et des conventions que les développeurs doivent suivre lors de l'extension/personnalisation de ses fonctionnalités . J'étends actuellement certaines de ses fonctionnalités administratives, auxquelles le framework fournit un contrat pour appliquer la mise en œuvre de la méthode GetAdministrationInterface(), qui retourne System.Web.UI.Control. Cette méthode est appelée pendant la fonction Page_Load() méthode de la page hébergeant l'interface GUI.

Problème: J'ai trois boutons dans mon interface graphique, dont chacun a été affecté à un gestionnaire d'événements. Mon interface graphique d'administration se charge parfaitement bien, mais cliquer sur l'un des boutons ne fait pas ce que j'attends d'eux. Cependant, lorsque je clique dessus une deuxième fois, les boutons fonctionnent.

J'ai placé des points d'arrêt au début de chaque méthode de gestionnaire d'événements et parcouru mon code. Au premier clic, aucun des gestionnaires d'événements n'a été déclenché. Au deuxième clic, ils ont tiré.

Des idées?

Exemple de définition de bouton (dans GetAdministrationInterface)

public override Control GetAdministrationInterface()
{
    // more code...

    Button btn = new Button();
    btn.Text = "Click Me!";
    btn.Click += new EventHandler(Btn_Click);

    // more code...
}

Exemple de définition de méthode de gestionnaire d'événements

void Btn_Click(object sender, EventArgs e)
{
    // Do Something
}

Page_Load Méthode qui appelle GetAdministrationInterface

protected void Page_Load(object sender, System.EventArgs e)
{
    if (!Page.IsAsync)
    {
        List<AdministrationInterface> interfaces = <DATABASE CALL>;
        foreach(AdministrationInteface ai in interfaces)
        {
            placeholderDiv.Controls.Add(ai.GetAdministrationInterface());
        }
    }
}
36
John

Bon chagrin! Je savais que ça allait être quelque chose d'aussi stupide. Purement ma faute bien sûr et mon manque de connaissances en ASP .NET.

Après avoir fait une multitude de recherches sur Google et finalement être bloqué par Google, soupçonné d'être un bot exécutant des scripts automatisés, j'ai réussi à insérer une dernière recherche et je suis tombé sur ce article . Déjà au point d'abandonner, j'ai fait de mon mieux pour lire l'article sans sauter 10 lignes à la fois ni chercher de jolies photos. Dans la section intitulée Attribuer des ID aux contrôles créés dynamiquement, j'ai lu ces mots magiques et joyeux:

Si vous affichez le code HTML source avant de cliquer sur le bouton qui ne fonctionne pas et après avoir cliqué dessus, vous remarquerez une petite différence. Les boutons ont différents ID HTML avant et après le post-back. J'ai eu ctl04 et ctl05 avant le post-back et ctl02 et ctl03 après le post-back.

Le bouton ASP.NET reconnaît les événements en recherchant une valeur pour son ID dans la collection Request.Form. (En réalité, cela se produit différemment et les contrôles ne vérifient pas la collecte de Request.Form par eux-mêmes. La page transmet les données de publication aux contrôles par leur ID et aux contrôles qui sont enregistrés pour être informés des données de publication). ASP.NET ne déclenche pas l'événement Click, car l'ID du bouton a changé entre les publications. Le bouton sur lequel vous avez cliqué et le bouton que vous voyez après sont différents boutons pour ASP.NET.

Effectivement, quand j'ai vu le HTML la première fois, mon bouton avait l'ID ctl04$ctl36. Après avoir cliqué sur le bouton, mon bouton avait l'ID ctl04$ctl33.

Alors voilà! Tout ce que j'avais à faire était de mettre l'ID sur les boutons et hop! Mes gestionnaires d'événements sont maintenant appelés!

Exemple de solution:

public override Control GetAdministrationInterface()
{
    // more code...

    Button btn = new Button();
    btn.Text = "Click Me!";
    // !!THE BANE OF MY EXISTENCE!!
    btn.ID = "The_Bane_of_My_Existence";
    // !!THE BANE OF MY EXISTENCE!!
    btn.Click += new EventHandler(Btn_Click);

    // more code...
}

Quelle belle façon de passer deux jours ...

66
John

J'ai eu le même problème, mais la réponse acceptée ici ne le causait pas. J'avais une zone de texte et un bouton de recherche, et cliquer sur le bouton la première fois n'a pas effectué la recherche. Le gestionnaire d'événements du bouton n'a pas été touché. Mais un deuxième clic sur le bouton a déclenché l'événement sur le serveur. Voici pourquoi:

Si vous avez un <asp:Textbox> avec son AutoPostBack réglé sur true, après avoir tapé dans la zone de texte puis déplacé pour cliquer sur un bouton, la zone de texte provoque une publication immédiatement au moment où elle perd le focus. Ainsi, le clic même du bouton ne compte pas (la page est déjà publiée à la suite de l'événement de la zone de texte). C'est pourquoi lorsque vous cliquez sur le bouton une deuxième fois, cela fonctionne car la zone de texte n'est pas impliquée dans le deuxième post-back.

Définissez la propriété AutoPostBack de la propriété <asp:Textbox> à false pour résoudre ce problème.

18
TheAgent

Une solution rapide consiste à définir un ID pour le contrôle ASCX que vous chargez sur une page. Par exemple, si votre code est comme ceci:

        UserControl SpecsControl = (UserControl)Page.LoadControl("../name.ascx");
        SpecsContainer.Controls.Add(SpecsControl);

alors vous devez ajouter une ligne (avant Controls.Add):

            SpecsControl.ID = "Aribtrary_Name";

Ensuite, votre méthode de gestionnaire est déclenchée au premier clic.

5
Farshid

Pour moi, c'était le UpdatePanel, mon Button et mon TextBox étaient tous deux à l'intérieur d'un UpdatePanel, donc quand je post-back, cela a causé un comportement bizarre. Il l'a pris en dehors du UpdatePanel et cela l'a corrigé.

1
JAN

J'étais confronté au même problème. Mon bouton s'est figé après mon premier clic. Pour moi, ce problème ennuyeux a été résolu lorsque j'ai désactivé l'attribut EnableViewState du bouton.

1
Gohan

Même moi, j'ai eu le même problème. la cause était "localhost: 1656/secure/login.aspx? ReturnUrl =% 2f". si la demande contient % 2f comme chaîne de requête, le premier message ne sera pas réussi même si "% 2f" représente "/".

une façon d'éviter cela en ayant une vérification de l'état dans pageload

protected void Page_Load(object sender, EventArgs e)
{
    string queryString = Request.QueryString.ToString();
    if(queryString == "ReturnUrl=%2f")
    {
        Response.Redirect("/secure/login.aspx");
    }
}
0
user2196633

Bien qu'il soit difficile de savoir exactement sans voir la méthode de publication complète, cela sent un peu comme si les gestionnaires d'événements ne se connectent pas tant que la page n'est pas rechargée.

par exemple:

if (IsPostBack) {
    // Add handlers here ...
}
0
Simon Rigby

J'ai eu le même problème. Et j'ai cherché sur internet je n'ai pas trouvé de solution. Après cela, j'ai trouvé un exemple de code et je l'ai utilisé. Ça a marché pour moi. Le lien du site Web est ci-dessous:

http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/calling-an-Asp-Net-C-Sharp-method-web-method-using-javascript/

0
Mahmut EFE