none
Comment appeler l'evenement d'un control crée par un evenement RRS feed

  • Question

  • Bonjour,

    Je cherche à créer une liste de bouton dynamiquement selon  la BD à qui j'associe un événement.
    Cet événement doit créer une nouvelle série de bouton dans un panel intermediaire selon la BD etc
    Un peu comme un arbre du genre "menu", "sous-menu" etc.

    Dans cet exemple, je n'ai qu'un bouton "menu" et un bouton "sous-menu", juste pour préciser mon problème.

    WebForm1.aspx :

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebForm1" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:ScriptManager ID="SM" runat="server"></asp:ScriptManager>
        <asp:UpdatePanel ID="UP" runat="server">
        <ContentTemplate>
            <asp:Panel ID="contenu" runat="server">
    
            </asp:Panel>
        </ContentTemplate>
        </asp:UpdatePanel>
        </form>
    </body>
    </html>

    WebForm1.aspx.cs :

    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Button boutonMenu = new Button();
            boutonMenu.Click += new EventHandler(boutonMenu_Click);
            boutonMenu.Text = "boutonMenu";
            contenu.Controls.Add(boutonMenu);
    
        }
        protected void boutonMenu_Click(object sender, EventArgs e)
        {
            Button boutonMenu = ((Button)sender);
            boutonMenu.Text += "*";
            Button boutonSousMenu = new Button();
            boutonSousMenu.Click += new EventHandler(boutonSousMenu_Click);
            boutonSousMenu.Text = "boutonSousMenu";
            boutonMenu.Parent.Controls.Add(boutonSousMenu);
        }
    
        protected void boutonSousMenu_Click(object sender, EventArgs e)
        {
            Button bouton = ((Button)sender);
            bouton.Text += "*";
    
        }
    }


    Résultat :
    Le boutonSousMenu n'est pas mis à jour avec une etoile mais disparait simplement. boutonSousMenu_Click n'est jamais appelé.
    J'ai cru comprendre que cela venait du fait que l'evenement PostBack executait Page_Load et donc supprimait mon boutonSousMenu (donc pas de boutonSousMenu_Click)

    Est ce qu'il y a un moyen de contourner ?
    Ou faut il que j'utilise une autre technologie ou d'autres contrôle ?

    Cordialement

    • Modifié william421 mercredi 11 avril 2012 08:39
    mercredi 11 avril 2012 08:39

Réponses

  • Bonjour,

    Ou plus exactement qu'une page ASP.NET est entièrement réinstanciée à chaque appel. Donc quand on clique sur boutonSousMenu, la classe qui représente la page est entièrement reconstruite, on ne passe par pas boutonMenu_Click, donc boutonSousMenu n'est pas recréé et à plus forte raison son évènement Click ne peut pas être géré.

    Les contrôles dynamiques doivent être recréés. Dans ce genre de cas, il est probablement plus simple d'avoir toujours boutonSousMenu et de jouer sur sa visibilité (cette propriété étant automatiquement maintenue entre deux appels) et de réserver la création de contrôle dynamique aux cas où l'on ne sait vraiment pas quoi faire jusqu'au dernier moment. Je ne suis pas sûr du résultat que l'on veut obtenir, voir peut-être asp:Menu (qui là aussi va maintenir automatiquement son état via le "viewstate").


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marqué comme réponse william421 mercredi 11 avril 2012 13:07
    mercredi 11 avril 2012 08:53
    Modérateur
  • J'ai un peu de mal à trouver qq chose en français (ca irait en anglais ?).

    Donc si on veut le faire en dynamique il faut recréer le contrôle boutonSousMenu dans Init pour qu'il existe et que l'évènement qui lui correspond puisse être géré. Il faudra aussi savoir que ce contrôle doit maintenant être affiché. J'essaierai de faire une petite démo tout à l'heure.

    Ou on peut éventuellement considérer que ces boutons sont générés depuis des données comme les autres (par exemple via un Repeater qui générerait les boutons qui correspondent à la source de données actuelles). J'essaierai éventuellement de faire une petite démo tout à l'heure pour #1...

    Finalement je trouve  http://msdn.microsoft.com/fr-fr/library/kyt0fzt1.aspx mais cela ne traite que l'ajout lui-même sans les implications.

    En résumé il faudrait recréer le contrôle le plus tôt possible dans le cycle de vie (et avoir qq chose qui nous indique que cette recréation est nécessaire, viewstate ou autre). En résumé, l'idée est que la structure de la page qui est recréée lors du postback doit-être identique à la structure de la page qui vient d'être affichée et qui a provoqué ce postback.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



    mercredi 11 avril 2012 13:21
    Modérateur

Toutes les réponses

  • Bonjour,

    Ou plus exactement qu'une page ASP.NET est entièrement réinstanciée à chaque appel. Donc quand on clique sur boutonSousMenu, la classe qui représente la page est entièrement reconstruite, on ne passe par pas boutonMenu_Click, donc boutonSousMenu n'est pas recréé et à plus forte raison son évènement Click ne peut pas être géré.

    Les contrôles dynamiques doivent être recréés. Dans ce genre de cas, il est probablement plus simple d'avoir toujours boutonSousMenu et de jouer sur sa visibilité (cette propriété étant automatiquement maintenue entre deux appels) et de réserver la création de contrôle dynamique aux cas où l'on ne sait vraiment pas quoi faire jusqu'au dernier moment. Je ne suis pas sûr du résultat que l'on veut obtenir, voir peut-être asp:Menu (qui là aussi va maintenir automatiquement son état via le "viewstate").


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marqué comme réponse william421 mercredi 11 avril 2012 13:07
    mercredi 11 avril 2012 08:53
    Modérateur
  • Bonjour,

    Merci pour votre réponse rapide.
    Après de plus ample recherche, je pense que le control TreeView devrait faire l'affaire. Je voulais une liste de panel mais je vais me débrouiller autrement.

    En jouant sur la visibilité, cela signifie prévoir tout les boutons possible. En supposant que j'ai 10 menu et que chaque menu à 10 sous-menu, j'ai 110 bouton à charger dans ma page. Alors que j'aurai aimé en avoir 20 simultanément (10 menu et 10 sous-menu du menu cliqué) pour éviter que ce soit trop lourd.

    mercredi 11 avril 2012 13:07
  • J'ai un peu de mal à trouver qq chose en français (ca irait en anglais ?).

    Donc si on veut le faire en dynamique il faut recréer le contrôle boutonSousMenu dans Init pour qu'il existe et que l'évènement qui lui correspond puisse être géré. Il faudra aussi savoir que ce contrôle doit maintenant être affiché. J'essaierai de faire une petite démo tout à l'heure.

    Ou on peut éventuellement considérer que ces boutons sont générés depuis des données comme les autres (par exemple via un Repeater qui générerait les boutons qui correspondent à la source de données actuelles). J'essaierai éventuellement de faire une petite démo tout à l'heure pour #1...

    Finalement je trouve  http://msdn.microsoft.com/fr-fr/library/kyt0fzt1.aspx mais cela ne traite que l'ajout lui-même sans les implications.

    En résumé il faudrait recréer le contrôle le plus tôt possible dans le cycle de vie (et avoir qq chose qui nous indique que cette recréation est nécessaire, viewstate ou autre). En résumé, l'idée est que la structure de la page qui est recréée lors du postback doit-être identique à la structure de la page qui vient d'être affichée et qui a provoqué ce postback.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



    mercredi 11 avril 2012 13:21
    Modérateur
  • Je pense avoir saisie l'idée de la re-création du bouton.

    Debutant en ASP.net, je n'ai pas encore eu affaire au viewstate (déjà que la cycle de vie d'une page...).
    Je vais donc regarder ce que c'est, comment ça fonctionne et ce que je peux en faire et si ça ne fonctionne pas, je vous recontacterai.

    Merci

    vendredi 13 avril 2012 08:49