Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C# Winform] Génération dynamique de contenu...

    1 mars 2012 à 11:19:05

    Salouté salouté,

    J'aimerais savoir s'il est possible de générer du contenu dynamiquement en C#. Je ne parle pas ici d'affiché un texte dans un lib, ou remplir un rtbox avec un champs de base de données.

    J'aimerais savoir s'il est possible, selon des informations préséntes dans ma BDD, de créer des objets graphique et de leur attribuer des fonctions.

    Mon problème :

    Je n'aime pas vraiment le fonctionnement des évenements en C#, notamment la fermeture, et l'ouverture d'autre page du form. On a des effets graphiques que je trouve grossier, c'est pas vraiment mon truc.

    Mon attente

    J'aimerais générer des menus dynamiquement, via un menu strip et par la programmation, j'ai vu qu'il était possible d'ajouter de nouveaux onglets à ce dernier. Cependant, comment dire quelle action il va effectuer lorsque je vais cliquer dessus ? Le simple fait d'incrémenter une variable m'aiderait grandement.

    Sa remedierait en plus à mes soucis d'evenement fermeture/ouverture de winforms, et ce sera un réel plus en terme de possibilités et de customisation.

    Merci bien !

    Je n'ai aucune ligne de code à l'heure actuelle, c'est juste une idée qui me passait par la tête...

    Bonne journée !
    • Partager sur Facebook
    • Partager sur Twitter
      1 mars 2012 à 13:27:34

      On dirait que tu confonds les événements du C# (en général) avec l'outil d'édition des WinForms permettant d'associer une méthode aux événements de tes contrôles.

      Chaque fois que tu crées une Form, un fichier TaForm.Designer.cs est généré par Visual Studio en plus du fichier TaForm.cs dans lequel tu écris son code. Tu devrais étudier le contenu de ce fichier : tu verras qu'en réalité tout est construit dynamiquement, mais tu as l'impression que c'est statique car l'initialisation de chaque Form a lieu dans son constructeur. Rien ne t'empêche d'écrire toi-même du code similaire à celui qui a été généré par Visual Studio et de l'utiliser où bon te semble. ;)

      Par ailleurs si tu veux avoir davantage de moyens de personnalisation pour ton interface, tu devrais t'intéresser à WPF.
      • Partager sur Facebook
      • Partager sur Twitter
        2 mars 2012 à 10:01:41

        Non non je ne les confonds pas :p

        Ce que je veux, c'est pouvoir générer le contenu graphique dynamiquement ET générer les actions effectué sur ce contenu dynamiquement.
        En gros dans mon appli, j'ajoute une rubrique à un menu, et je gère, sur l'event "clic" un affichage d'une messagebox.

        L'afficher dynamiquement, ca n'est plus un problème avec ta solution. Cependant, comment je peux faire pour éditer, sans accéder au code, le contenu de la méthode clic ?
        • Partager sur Facebook
        • Partager sur Twitter
          2 mars 2012 à 11:41:05

          Avec la reflection?

          Grâce à ça, tu peux associer (dynamiquement) une méthode à un événement...Tu peux même générer du code entièrement dynamique grâce aux outils présents dans System.Reflection.Emit. Cependant, l'émission de code IL nécessite de connaître comment fonctionne la CLR lorsqu'elle analyse le code IL pour la compilation en natif. Si tu génère un code erroné (par exemple en omettant de rajouter un OpCodes.Ret après chaque code de méthode générée, même si elle retourne "void"), tu auras sans doute droit à une exception te disant qu'un appel va "déstabiliser la pile d'appel" sans plus de détail sur l'origine exacte de l'erreur.

          *L'émission de code dynamique, c'est super-passionnant je trouve...Mais c'est aussi super long, très fastidieux et rapidement lourd*
          • Partager sur Facebook
          • Partager sur Twitter
            2 mars 2012 à 11:59:23

            Oulà Nisnor ne l'entraine pas dans cette direction-là, je doute qu'il en ait besoin. :-° Je pense qu'il faut juste que Minkow s'habitue à accrocher un gestionnaire d'événement à un événement.

            Par exemple, voici comment créer dynamiquement un bouton et définir l'action à effectuer en cas de clic :

            // Ce code est à placer "dans une Form"
            public void AddButton()
            {
                Button button = new Button();
                button.Text = "Clique ici";
                button.Click += OnButtonClicked;
                this.Controls.Add(button);
            }
            
            private void OnButtonClicked(object sender, EventArgs e)
            {
                Button button = (Button)sender;
                sender.Text = "Merci d'avoir cliqué";
            }
            

            En gros c'est tout simple : on crée un bouton qu'on ajoute aux contrôles de la Form (ou à un de ses contrôles enfant), et on spécifie la méthode à exécuter en cas de clic. Cette méthode doit respecter une signature particulière. Dans celle-ci, le paramètre sender représente l'objet qui a émis l'événement.

            Une manière un peu plus avancée de faire la même chose consiste à utiliser une méthode anonyme pour gérer l'événement Click:

            public void AddButton()
            {
                Button button = new Button();
                button.Text = "Clique ici";
                button.Click += delegate(object sender, EventArgs e)
                {
                    button.Text = "Merci d'avoir cliqué";
                };
                this.Controls.Add(button);
            }
            

            De cette manière on peut réutiliser des variables qui auraient été définies en dehors du scope de la méthode anonyme (on parle de fermeture, closure en anglais). Ca évite de devoir caster le paramètre sender.

            Ici comme il n'y a qu'une action à effectuer en cas de clic, on peut même réduire encore le code :

            public void AddButton()
            {
                Button button = new Button();
                button.Text = "Clique ici";
                button.Click += (s, e) => button.Text = "Merci d'avoir cliqué";
                this.Controls.Add(button);
            }
            

            @Minkow : avec ce code, tu devrais pouvoir trouver comment ajouter un élément à ton menu et gérer son événement clic. :)
            • Partager sur Facebook
            • Partager sur Twitter
              2 mars 2012 à 15:53:48

              Citation : Orwell

              Oulà Nisnor ne l'entraine pas dans cette direction-là, je doute qu'il en ait besoin. :-° Je pense qu'il faut juste que Minkow s'habitue à accrocher un gestionnaire d'événement à un événement.


              :p Mais...Mais le Mr y veut des trucs dynamique...Je lui sors des trucs dynamiques :p


              Plus sérieusement, s'il veut faire des trucs réellement dynamique suivant ce pseudo-code :
              Utilisateur Place Bouton
                  + Saisie d'Action à lier
                       | Enregistrement en base de l'interface utilisateur
                      ou
                       | Annulation
              [...]
              Utilisateur Teste Interface
                  + Initialisation des composants suivant modèle en base
                         -Si BoutonClic
                                 + Exécute Code Personnalisé

              soit il fait des if-elseif-else/switch dans tous les sens et les possibilités resteront "relativement" limitées...Soit il utilise la reflection (avec l'émission de code IL) :lol:.

              J'avoue ne pas trop comprendre ce qu'il veut dans "Cependant, comment je peux faire pour éditer, sans accéder au code, le contenu de la méthode clic ? "
              • Partager sur Facebook
              • Partager sur Twitter
                3 mars 2012 à 3:34:45

                J'ai pas trop compris mais pourquoi ne pas enregistrer dans un fichier l'état de ta form (contrôles, propriétés, etc...) et de les charger quand l'application se lance. Ainsi pour changer l'interface tu n'as qu'à changer ce fichier lorsque l'utilisateur entre une nouvelle option, tu lui demande de redémarrer ton appli' pour recharger le contenu ou tu rappelle une méthode faite pour ça. Bon après c'est certainement assez sale comme truc...
                • Partager sur Facebook
                • Partager sur Twitter
                "Il est impossible pour un homme d'apprendre ce qu'il croit déjà connaître"
                  4 mars 2012 à 11:52:22

                  Tout dabord merci de vos réponses, je vais travailler la dessus, et je reviendrais au besoin.

                  Pour être un peu plus clair :

                  En PHP, on peut stocker dans une BDD différents pages, en gérant des contenus. Via $_GET et $_POST, il est possible de récupérer des id en paramètre correspondant à une page, et d'en afficher le contenu dynamiquement.

                  Concrètement, dans ma BDD, j'ai une table "page", à laquelle j'associe un titre, un contenu.

                  Je génère dynamiquement mon Menu (dans une boucle). Dans chaque bouton je redirige l'utilisateur sur la même page, en changeant le paramètre en $_GET. Ainsi lors du clic sur le premier bouton, j'ai accès à la page dont la PK est 1 (index.php?id=1).

                  Ca me permet d'avoir autant de page que je le souhaite, d'en rajouter au besoin, et même d'en supprimer via une interface adéquate.

                  Je voulais essayer de reproduire ce schéma en C# WinForm, mais apparemment, la simplicité de réalisation en PHP n'est pas vraiment présente en C#. Je vais donc essayer de bosser ce que vous m'avez apporté, en vous remerciant bien sur.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    4 mars 2012 à 12:23:49

                    Ce n'est pas plus difficile de faire ça en C# qu'en PHP : c'est juste très différent.

                    En PHP tu "écris" des fragments de HTML afin de constituer une page à renvoyer au navigateur. Chaque requête GET ou POST se traduit par la génération d'une page HTML (ou éventuellement d'un objet JSON si c'est une requête AJAX).

                    En WinForms il n'y a pas d'interaction client-serveur constante : ton code est "côté client", pas "côté serveur". En fait la manière d'agir sur les éléments d'une Form et de gérer les événements est plus proche d'un code Javascript que d'un code PHP - sauf que le DOM ici n'est pas constitué d'éléments HTML mais de contrôles WinForms. Si tu as déjà écrit du code Javascript pour créer des pages dynamiques, base-toi plutôt sur cette expérience-là. ;)

                    À propos pour réaliser ce genre d'application, WPF est en fait plus adapté que WinForms. Mais là on change complètement de paradigme pour créer ses écrans, et il vaut sans doute mieux que tu t'habitues d'abord à l'approche "code-behind" commune aux WinForms et au Javascript pour bien cerner ses avantages et faiblesses avant de découvrir une approche plus "moderne". ;)
                    • Partager sur Facebook
                    • Partager sur Twitter

                    [C# Winform] Génération dynamique de contenu...

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown