Problème de Click Event sur button dynamic

Problème de Click Event sur button dynamic - C#/.NET managed - Programmation

Marsh Posté le 13-04-2007 à 10:32:13    

Bonjour,
 
dans mon code C#, j'ai créé dynamiquement 10 button. Quand je clique dessus sur le site, il ne rentre pas dans la méthode buttonKBokKeywords_Click.
 
J'ai testé en créant un button via le design de visual studio et en mettant dans properties comme attribut Click "buttonKBokKeywords_Click" -> sur le site, ca appel la méthode quand je clique sur ce bouton.
 
-> pourquoi ca ne fonctionne pas avec mes dynamics button?
 
voici le code.
[edit]

Code :
  1. for (int X = 1; X < 10;X++)
  2. {
  3.                 Button b = new Button();
  4.                 b.Text = ""+X;
  5.                 b.ID = "bttnPage"+X;
  6.                 b.Click += new System.EventHandler(buttonKBokKeywords_Click);
  7.                 panel.Controls.Add(b);
  8. }


[/edit]
 
 
-> mon panel aura 10 boutons comme ID : bttnPage1 bttnPage2 bttnPage3...
 
merci!


Message édité par shibawis le 13-04-2007 à 11:44:03
Reply

Marsh Posté le 13-04-2007 à 10:32:13   

Reply

Marsh Posté le 13-04-2007 à 10:52:06    

1) merci d'utiliser les balises code pour poster du code
2) normal que ça ne fonctionne pas, puisque tu écrases à chaque fois ta référence b en créant un nouveau bouton... il faut stocker tes boutons dans une collection au fur et à mesure de leur création (ArrayList ou autre par exemple)
3) là tu fais n'importe quoi :

Code :
  1. b.Text = ""+X;
  2. b.ID = "bttnPage"+X;


X est un int, et les propriétés Text et ID sont des strings. il faut convertir X en string avec ToString() si tu veux le concaténer à une autre string

Reply

Marsh Posté le 13-04-2007 à 10:59:51    

I've loled


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 13-04-2007 à 11:07:12    

Reply

Marsh Posté le 13-04-2007 à 11:40:01    

1) ok.
 
2) j'ai stocké dans un tableau chacun des button créés, et ensuite je les ai ajoutés au panel. Le problème subsiste quand je clique dessus, le button n'appelle pas la méthode. -> ce n'est pas un problème de référence écrasée
 
3) je ne pense pas que c'est n'importe quoi.
En mettant un "" devant mon int, il va automatiquement le convertir en string.
quand ma page est compilé, voici le code source généré.
 
mon button créé depuis le design drag&drop :
 

Code :
  1. <input type="submit" name="bttnPage1" value="1"
  2. onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;bttnPage1&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))"
  3. id="bttnPage1"/>


 
et deux des button créé depuis mon code :
 

Code :
  1. <input type="submit" name="**bttnPage1" value="1"
  2. onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;**bttnPage1&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))"
  3. id="**bttnPage1" />
  4. <input type="submit" name="**bttnPage2" value="2"
  5. onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;**bttnPage2&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))"
  6. id="**bttnPage2" />


 
il a bien concaténé mon int au string.
 
 
autre idée?

Message cité 2 fois
Message édité par shibawis le 13-04-2007 à 11:47:22
Reply

Marsh Posté le 13-04-2007 à 11:49:38    

Reply

Marsh Posté le 13-04-2007 à 11:55:01    

de rien [:dawa]

Reply

Marsh Posté le 13-04-2007 à 12:03:18    

shibawis a écrit :


3) je ne pense pas que c'est n'importe quoi.
En mettant un "" devant mon int, il va automatiquement le convertir en string.
quand ma page est compilé, voici le code source généré.

 

mon button créé depuis le design drag&drop :

  

et deux des button créé depuis mon code :

 
Code :
  1. <input type="submit" name="**bttnPage1\" value=\"1\"
  2. onclick=\"javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;**bttnPage1&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))\"
  3. id=\"**bttnPage1\" />
  4. <input type=\"submit\" name=\"**bttnPage2\" value=\"2\"
  5. onclick=\"javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;**bttnPage2&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))\"
  6. id=\"**bttnPage2\" />
 

il a bien concaténé mon int au string.

 


autre idée?


mon dieu .... laisse moi deviner ... tu fesais pas du PHP avant ?

 


Message édité par Koyomi le 13-04-2007 à 12:03:42
Reply

Marsh Posté le 13-04-2007 à 12:13:12    

je n'ai jamais fait de php et j'ai quelques notions en html, pourquoi dis tu ça ?
 
 
j'ai regardé mon code source généré pour montrer qu'il avait bien concaténé ce code.
ce n'est pas n'importe quoi de travailler ainsi.
 

Code :
  1. b.Text = ""+X;               
  2. b.ID = "bttnPage"+X;

Reply

Marsh Posté le 13-04-2007 à 13:01:44    

shibawis a écrit :

je n'ai jamais fait de php et j'ai quelques notions en html, pourquoi dis tu ça ?
 
 
j'ai regardé mon code source généré pour montrer qu'il avait bien concaténé ce code.
ce n'est pas n'importe quoi de travailler ainsi.
 


 
Alors non ce n'est pas du n'importe quoi de travailler ainsi c'est juste du grand n'importe quoi.
 
en .NET il y a des méthode ToString() sur tout objet
 
Ton code devrait etre :  
 

Code :
  1. b.Text = X.ToString();
  2. b.ID = "bttnPage" + X.ToString();


 


Message édité par Koyomi le 13-04-2007 à 13:02:08
Reply

Marsh Posté le 13-04-2007 à 13:01:44   

Reply

Marsh Posté le 13-04-2007 à 13:22:14    

voilà, j'ai modifié le grand n'importe quoi.
le problème persiste pour l'appel de la méthode.

Reply

Marsh Posté le 13-04-2007 à 13:35:53    

Montre nous le code en entier, car comme cela c'est pas évident de te dire ce qui ne fonctionne pas :S

Reply

Marsh Posté le 13-04-2007 à 14:00:06    

Code :
  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3.         txtDebug.Text = "page_load";
  4. }
  5. protected void buttonKBokKeywords_Click(object sender, EventArgs e)
  6. {
  7.             //message pour savoir quel bouton a été cliqué
  8.             txtDebug.Text = "sender?" + ((Button)sender).ID;
  9.             Button[] listButton = new Button[10];
  10.             //mes 10 boutons que je génère
  11.             for (int X = 0; X < 10;X++)
  12.             {
  13.                 Button b = new Button();
  14.                 b.Text = X.ToString();
  15.                 b.ID = "**bttnPage" + X.ToString();
  16.                 b.Click += new System.EventHandler(buttonKBokKeywords_Click);//préciser quelle méthode appeler quand je clique sur le bouton
  17.                 listButton[X] = b;//pour éviter d'écraser la référence - cf post précédent
  18.             }
  19.            
  20.             //ajout des 10 boutons dans mon panel
  21.             for (int X = 0; X < 10;X++)
  22.             {
  23.                 pnlKBPagination.Controls.Add(listButton[X]);
  24.             }
  25. }


 
 
voilà.
Quand je clique sur mon button que j'ai crée via le design ID=bttnPage1 et qui possède un event properties Click = buttonKBokKeywords_Click.
-> je rentre dans la méthode et ca m'affiche :
 
sender?bttnPage1
 
 
Quand je clique sur un des button que j'ai généré dans ce code
-> je ne rentre pas dans la méthode et ca m'affiche tout simplement :
 
page_load
 
pourtant j'ai bien spécifié

Code :
  1. b.Click += new System.EventHandler(buttonKBokKeywords_Click);


il devrait m'afficher :
 
sender?**bttnPageX  
(X étant le numéro du button que j'ai cliqué)
 
 
 
j'espère que c'est plus clair!


Message édité par shibawis le 13-04-2007 à 14:01:10
Reply

Marsh Posté le 13-04-2007 à 14:57:53    

shibawis a écrit :


2) j'ai stocké dans un tableau chacun des button créés, et ensuite je les ai ajoutés au panel. Le problème subsiste quand je clique dessus, le button n'appelle pas la méthode. -> ce n'est pas un problème de référence écrasée


au temps pour moi, j'avais pas vu que tu créais à chaque fois un new Button() dans le for. poste le code complet stp

 
shibawis a écrit :


3) je ne pense pas que c'est n'importe quoi.
En mettant un "" devant mon int, il va automatiquement le convertir en string.
quand ma page est compilé, voici le code source généré.


si c'est n'importe quoi, et si ça marche c'est parce que .NET fait ce qu'il faut pour que ça marche. un exemple :

 
Code :
  1. namespace ConsoleApplication1
  2. {
  3.    class Program
  4.    {
  5.        static void Main(string[] args)
  6.        {
  7.            int i = 3;
  8.            string leopard = "kikoo";
  9.            string ficelle = leopard + i;
  10.            Console.WriteLine(ficelle);
  11.        }
  12.    }
  13. }


un programme tout con, qui concatène une string et un int. et O surprise, effectivement ça fonctionne.

 

regardons le MSIL produit par ce programme, c'est très instructif :

Code :
  1. .method private hidebysig static void  Main(string[] args) cil managed
  2. {
  3.   .entrypoint
  4.   // Code size       28 (0x1c)
  5.   .maxstack  2
  6.   .locals init ([0] int32 i,
  7.            [1] string leopard,
  8.            [2] string ficelle)
  9.   IL_0000:  ldc.i4.3
  10.   IL_0001:  stloc.0
  11.   IL_0002:  ldstr      "kikoo"
  12.   IL_0007:  stloc.1
  13.   IL_0008:  ldloc.1
  14.   IL_0009:  ldloc.0
  15.   IL_000a:  box        [mscorlib]System.Int32
  16.   IL_000f:  call       string [mscorlib]System.String::Concat(object,
  17.                                                               object)
  18.   IL_0014:  stloc.2
  19.   IL_0015:  ldloc.2
  20.   IL_0016:  call       void [mscorlib]System.Console::WriteLine(string)
  21.   IL_001b:  ret
  22. } // end of method Program::Main
 

les lignes importantes sont la 000a et la 000f.

 

sur la 000a, l'instruction box est appelée avec comme argument le type System.Int32. ce qui signifie que la variable locale 0, donc i, est empilée, puis transmise à box qui se charge de la convertir du type int32 en System.Int32, rendant ainsi possible l'appel à ToString(). Puis la ligne suivante appelle la méthode String.Concat(), qui se charge de concaténer la représentation chaine (via un appel masqué à ToString) des 2 variables pour produire une nouvelle chaine.

 

Que se serait il passé si au lieu de taper ceci

Code :
  1. string ficelle = leopard + i;


j'avais tapé ceci :

Code :
  1. string ficelle = leopard + i.ToString();
 

IL :

Code :
  1. .method private hidebysig static void  Main(string[] args) cil managed
  2. {
  3.   .entrypoint
  4.   // Code size       29 (0x1d)
  5.   .maxstack  2
  6.   .locals init ([0] int32 i,
  7.            [1] string leopard,
  8.            [2] string ficelle)
  9.   IL_0000:  ldc.i4.3
  10.   IL_0001:  stloc.0
  11.   IL_0002:  ldstr      "kikoo"
  12.   IL_0007:  stloc.1
  13.   IL_0008:  ldloc.1
  14.   IL_0009:  ldloca.s   i
  15.   IL_000b:  call       instance string [mscorlib]System.Int32::ToString()
  16.   IL_0010:  call       string [mscorlib]System.String::Concat(string,
  17.                                                               string)
  18.   IL_0015:  stloc.2
  19.   IL_0016:  ldloc.2
  20.   IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
  21.   IL_001c:  ret
  22. } // end of method Program::Main


on constate que le box a disparu au profit d'un appel à ToString().

 

En résumé : ça marche parce que tu es tenu par la main. Mais c'est loin d'être une généralité, et en C, C++ ou autre, ce genre de truc te conduit directement à l'erreur de compilation. Donc autant prendre de bonnes habitudes et coder correctement.

 

Quelques réferences très utiles :
la publication ECMA du MSIL, très très instructif (pour ne pas dire indispensable) : http://www.ecma-international.org/ [...] ma-335.pdf

 

quelques trucs pour optimiser du VB .NET (valable aussi en C#):
http://www.microsoft.com/france/ms [...] ances.mspx


Message édité par Harkonnen le 13-04-2007 à 14:59:11

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 13-04-2007 à 15:12:13    

ok je vois.
j'en prends note!
merci

Reply

Marsh Posté le 13-04-2007 à 15:14:52    

je continue a penser que c'est n'importe quoi son code. Rien qu'a voir un control qui s'appelle "txtDebug" ca laisse présager du meilleur. Laisse moi deviner, les breakpoints tu connais pas ?


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 13-04-2007 à 15:17:45    

Ne cherche pas plus loin ton erreur est la :

 
Code :
  1. protected void buttonKBokKeywords_Click(object sender, EventArgs e)
  2. {
  3.    txtDebug.Text = "sender?" + ((Button)sender).ID;
  4.    Button[] listButton = new Button[10];
  5.    for (int X = 0; X < 10;X++)
  6.    {
  7.       Button b = new Button();
  8.       b.Text = X.ToString();
  9.       b.ID = "**bttnPage" + X.ToString();
  10.      
  11.       b.Click += new System.EventHandler(buttonKBokKeywords_Click); // ICI
  12.       listButton[X] = b;
  13.    }


Je te décrit ce que fait ta méthode.

 

Lors du click sur le bouton "buttonKBokKeywords" je déclenche l'événement "buttonKBokKeywords_Click" je crée 10 boutons auquel j'affecte la méthode "buttonKBokKeywords_Click" lors d'un clic sur l'un d'entre eux.

 

Bref cela n'a pas de sens.

 

Remplace plutot par cela:

 
Code :
  1. protected void buttonKBokKeywords_Click(object sender, EventArgs e)
  2. {
  3.    txtDebug.Text = "sender?" + ((Button)sender).ID;
  4.    Button[] listButton = new Button[10];
  5.    for (int X = 0; X < 10;X++)
  6.    {
  7.       Button b = new Button();
  8.       b.Text = X.ToString();
  9.       b.ID = "**bttnPage" + X.ToString();     
  10.       b.Click += new System.EventHandler(buttonKBokKeywordsGenerated_Click); // ICI
  11.       listButton[X] = b;
  12.    }
  13.   //Blabla
  14. }
  15. protected void buttonKBokKeywordsGenerated_Click(object sender, EventArgs e)
  16. {
  17. // Ton code a executer lorsque l'on clique sur un des boutons générés à la volée
  18. }
 

Message cité 1 fois
Message édité par Koyomi le 13-04-2007 à 15:19:40
Reply

Marsh Posté le 13-04-2007 à 15:18:36    

Non, c'est une nouvelle voiture? [:dawa]

Reply

Marsh Posté le 13-04-2007 à 15:33:38    

IWHFP


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 13-04-2007 à 15:34:16    

Koyomi a écrit :

Ne cherche pas plus loin ton erreur est la :


ah purée, j'avais pas vu qu'il avait posté son code [:mlc]
évidemment, s'il créé ses boutons dans la callback, ça risque pas de marcher [:mlc]

Reply

Marsh Posté le 13-04-2007 à 15:46:59    

Harkonnen a écrit :

ah purée, j'avais pas vu qu'il avait posté son code  [:mlc]
évidemment, s'il créé ses boutons dans la callback, ça risque pas de marcher  [:mlc]


Il a poster heuresement que quelques lignes ... j'ose a peine immaginer le reste :)

Reply

Marsh Posté le 13-04-2007 à 15:54:44    

Tamahome a écrit :

je continue a penser que c'est n'importe quoi son code. Rien qu'a voir un control qui s'appelle "txtDebug" ca laisse présager du meilleur. Laisse moi deviner, les breakpoints tu connais pas ?


 
txtDebug est une textBox qui est sur le site, ainsi je peux me ballader sur le site et voir différentes informations de mon code sans devoir passer par les breakpoints.
 
 
Tamahome & Petitpois2, si c'est pour spammer et vous moquez, sans donner une quelconque aide, pas besoin de venir poster. vous ne pensez pas ?
 
 
 
 
Je vais vous expliquer ce que je fais.
 
L'utilisateur introduit 1 ou plusieurs mots clés et fais OK.
Là je vais avoir un certain nombre de titres correspondant à sa recherche.
Les titres s'affichent par 10.
Si j'ai 40 titres trouvés, j'aurais 4 boutons qui me permettront d'aller voir les titres par pallier.
bouton 1 => titres 0-10
bouton 2 => titres11-20
etc.
Si j'ai 100 titres trouvés, j'aurais 10 boutons
 
-> dans mon code je génère mes 10 boutons
 
 
Koyomi, je vais essayer ce que tu me proposes

Code :
  1. b.Click += new System.EventHandler(buttonKBokKeywordsGenerated_Click);


 


Message édité par shibawis le 13-04-2007 à 16:01:03
Reply

Marsh Posté le 13-04-2007 à 16:11:07    

j ai modifié mon code et mis un message dans la méthode buttonKBokKeywordsGenerated_Click
quand je clique sur un des boutons, ça n'affiche pas le message, donc n'entre pas dans la méthode.
 
 
c'est bien un problème de event, non?

Message cité 1 fois
Message édité par shibawis le 13-04-2007 à 16:11:50
Reply

Marsh Posté le 13-04-2007 à 16:12:37    

poste le code que t'as fait, t'as du te mélanger les pinceaux grave...

Reply

Marsh Posté le 13-04-2007 à 16:18:30    

Harkonnen a écrit :

poste le code que t'as fait, t'as du te mélanger les pinceaux grave...


 

Code :
  1. protected void buttonKBokKeywords_Click(object sender, EventArgs e)
  2.     {
  3.             Button[] listButton = new Button[10];
  4.             for (int X = 0; X < 10;X++)
  5.             {
  6.                 Button b = new Button();
  7.                 b.Text = X.ToString();
  8.                 b.ID = "**bttnPage" + X.ToString();
  9.                 b.Click += new System.EventHandler(buttonKBokKeywordsPagination_Click);
  10.                 listButton[X] = b;
  11.             }
  12.             for (int X = 0; X < 10;X++)
  13.             {
  14.                 pnlKBPagination.Controls.Add(listButton[X]);
  15.             }
  16.     }
  17.     protected void buttonKBokKeywordsPagination_Click(object sender, EventArgs e)
  18.     {
  19.         txtDebug.Text += "ici";
  20.     }


 
vous pouvez tester, et me dire si ca fonctionne chez vous

Reply

Marsh Posté le 13-04-2007 à 16:21:52    

et la ligne

Code :
  1. b.Click += new System.EventHandler(buttonKBokKeywords_Click);


elle est ou ?

Reply

Marsh Posté le 13-04-2007 à 16:24:00    

j'ai remplacé par  
 
 

Code :
  1. b.Click += new System.EventHandler(buttonKBokKeywordsPagination_Click);


 
pour pouvoir appeler une autre méthode que celle où je créé mes boutons.
 
 

Code :
  1. protected void buttonKBokKeywordsPagination_Click(object sender, EventArgs e)    {        txtDebug.Text += "ici";    }

Reply

Marsh Posté le 13-04-2007 à 16:37:09    

ok, mais la méthode dans laquelle tu créé tes boutons, tu l'appelles comment et quand ?

Reply

Marsh Posté le 13-04-2007 à 16:42:21    

Harkonnen a écrit :

ok, mais la méthode dans laquelle tu créé tes boutons, tu l'appelles comment et quand ?


 
dans mon design visual studio, j'ai un button que j'ai créé en drag&drop. Dans ces propriétés -> event -> Click : buttonKBokKeywords_Click
 
quand je clique sur ce bouton, il lance ma méthode buttonKBokKeywords_Click qui créé mes 10 boutons qui iront dans le panel.
ces 10 boutons ont un event Click : buttonKBokKeywordsPagination_Click que j'ai défini dans le code de la méthode buttonKBokKeywords_Click


Message édité par shibawis le 13-04-2007 à 16:44:40
Reply

Marsh Posté le 14-04-2007 à 09:40:20    

shibawis a écrit :

j ai modifié mon code et mis un message dans la méthode buttonKBokKeywordsGenerated_Click
quand je clique sur un des boutons, ça n'affiche pas le message, donc n'entre pas dans la méthode.
 
 
c'est bien un problème de event, non?


 
non, pas forcément. Utilise les breakpoints.


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 16-04-2007 à 14:07:45    

bonjour,
 
j'ai trouvé l'explication du problème.
 
"le bouton est ajouté dynamiquement, il faut systématiquement l'ajouter dans chaque chargement de votre page."
 
vu qu'ils sont créés dans une méthode autre que le page_load, dès que je click dessus, il y a un chargement de ma page, et mes boutons n'existent plus. -> impossibler d'aller dans leur event
 
 
merci pour toutes vos réponses


Message édité par shibawis le 16-04-2007 à 14:09:01
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed