Partage
  • Partager sur Facebook
  • Partager sur Twitter

appeler un objet d'une classe dans une autre C#

    1 mars 2019 à 12:21:18

    Bonjour à tous,

    Je programme habituellement en VB.net et je me lance en C# donc débutant.

    Je suis face à un problème en C# qui n'en est pas un en VB..

    J'ai une form que l'on va appeler form1 qui possède un datagridview DGV, puis j'ai une classe que l'on va nommer Class.

    J'ai pour habitude de créer des méthodes dans ma classe puis de les appeler derrière un bouton de ma form1 par exemple afin de ne pas avoir la partie code dans form1.vb (c'est mon choix).

    En VB.net aucuns problème dans ma form1 je fais :

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Class.Methode() End Sub

    Puis dans ma classe Class j'appelle mon Datagridview :

    Public Shared Sub Methode()
    
    form1.DGV.Columns("ID").Visible = False
    
    End Sub


    Sauf qu'en C# il ne m'est pas possible de faire comme ça :

     public static void Methode()
            {
    
                
                form1.DGV.Columns["ID"].Visible = false;
    
            }


    Il me dit qu'il manque une référence d'objet pour la propriété, la méthode ou le champ statique.

    J'ai essayé plusieurs choses comme :

    public class Class
        {
    
           form1 MyParentForm;
    
    public void Methode()
            {
    
    ((form1)MyParentForm).DGV.Columns["ID"].Visible = false;
    
    }

    Mais pour que le code ci dessus fonctionne j'ai du enlever static à ma méthode ce qui fait que je ne peux plus y accéder dans le code de ma form1, c'est donc le serpent qui se mort la queue..

    Je vous remercie de l'aide que vous pourrez m'apporter.

    • Partager sur Facebook
    • Partager sur Twitter
    Ce n'est pas en voulant améliorer la bougie que l'on a découvert l'électricité
      1 mars 2019 à 12:33:43

      Ton «choix» est douteux (au mieux) avoir un couplage fort entre une classe externe est le formulaire ou avoir le code dans le formulaire (surtout que le principe des classes partielles à été pensé pour ça) c'est bonnet blanc et blanc bonnet.

      Après solution «simple» pour résoudre le problème (et enlever une partie du couplage) faire en sorte que tes méthodes prennent en argument(s) ce sur quoi elles doivent agir.

      Ici, par exemple, on pourrait prendre un argument de type form1 (ou mieux, de type DataGridView) 

      -
      Edité par Sehnsucht 1 mars 2019 à 12:34:13

      • Partager sur Facebook
      • Partager sur Twitter
      Censément, quelqu'un de sensé est censé s'exprimer sensément.
        1 mars 2019 à 12:50:32

        Merci pour ta réponse Sehnsucht,

        Je ne suis pas obtus donc ouvert aux remarques, je voudrais t'expliquer mon "choix" :

        Habituellement en Vb je conçoit ne nombreuses applications qui disposent de plusieurs formulaire, j'aime bien créer une classe (class.vb par exemple) pour y ranger un grand nombre de méthodes puis de n'importe quel formulaire je viens appeler la méthode voulu de la classe "class", ça me permet de concentrer mon code dans une seule classe c'est simplement plus clair pour moi (Peut être un héritage du C à l'époque..).

        Pourrais tu me dire pourquoi ce n'est pas bon ou maladroit de procéder ainsi?

        Tu me recommanderais de créer les méthodes concernant le formulaire1 dans le formulaire1 etc..?

        Je te remercie

        • Partager sur Facebook
        • Partager sur Twitter
        Ce n'est pas en voulant améliorer la bougie que l'on a découvert l'électricité
          1 mars 2019 à 16:19:05

          Hello,

          Je suis pas assez calé pour répondre de manière claire et précise a la question du pourquoi est ce maladroit ou pas très bon de procéder comme tu le fais. Je peux en revanche te diriger vers les concepts de MVC (ou MVP, un derivé de MVC bien adapté à WinForm). C'est ces patterns qui te permettront de bien cloisonner ta partie code métier de la partie vue.

          Cependant ce que te proposes Sehnsuch c'est de passer en paramètre les objets de ta Form sur lesquelles tu souhaites interagir, en gros faire quelque chose du genre :

          public class Class{
              public Class(){}
              public void taMethode(DataGridView unDgv){
                  unDgv.Columns["ID"].Visible=false;
          }}

          Sinon tu peux aussi passer le formulaire entier dans le constructeur de ton objet Classe mais je pense que c'est VRAIMENT pas propre de faire ca 

          En esperant t'avoir aidé

          -
          Edité par earp91 1 mars 2019 à 16:27:24

          • Partager sur Facebook
          • Partager sur Twitter
            1 mars 2019 à 19:08:17

            Bonne motivation mais mise en œuvre très approximative.

            Mise en œuvre qui peut être facilement faites uniquement en utilisant des "fonctionnalités" très contre-versées de VB.NET (séquelles de l'histoire peu glorieuse de VB non objet des années 90).

            Votre motivation de ne pas mettre du code qui n'a rien à voir avec l'interface utilisateur dans une partie distincte du formulaire est une initiative des plus saines.

            Votre approche pour le faire est malheureusement très maladroite.

            L'héritage du C vous a appris le concept de "modularité" à base de couches.

            Dans une approche C, vous vous basez sur des couches et pas des objets.

            Dans votre approche "à la C", vous avez une couche IHM et une couche métier. Chose qui est aussi très répondu dans d'autres langages et framework.

            Mais dans une approche en couche, la couche métier est indépendante de la couche IHM.

            Hors, l'utilisation de type spécifique à la couche d'IHM (form, DGV, etc...) invalide complètement votre approche en couche, juste pour faire passer votre bricolage. Cela peut fonctionner mais cela rend votre découpage complètement inutile, voir contre-productif.

            Ce que propose @Sehnsucht a les mêmes gros défauts de couplage entre les couches, mais vous permets de ne plus dépendre des "fonctionnalités" spécifiques VB.NET.

            Pour correctement mettre en œuvre le découpage en couche, il faut bien distinguer et modéliser chaque couche de manière indépendante. Les couches du bas (métier ici) ne dépendant pas des couches supérieures (IHM ici) et les couches supérieures ne dépendant que d'une API claire de la couche immédiatement inférieure.

            Cette API ne doit pas dépendre de détails d'implémentation de la couche la fournissant.

            Dans votre approche, la couche base est, très probablement, un capharnaüm de fonctions utilitaires décousues, sans unités ni concepts "émergeant" qu'une approche vraiment objet cherche à promouvoir.

            Factoriser les services offerts par une couche sous forme de classe/d'instance est une des actions fondamentales de la POO (Programmation Orientée Objet).

            Winform a été pensé en POO, sans les infâmes "tricks" de VB.NET. Il est donc peu surprenant qu'en ne respectant pas la POO, on se retrouve à galérer.

            Pour éviter le couplage fort entre vos couche mais que cela reste simple, je vous conseille l'usage d'objet type DTOs entre vos couches, comme un simple DataSet.

            Le DataBinding permettra une mise à jour automatique de l'interface graphique.

            Mais si on reprend concrètement ce que fait votre code, c'est planquer une colonne dans l'Interface. C'est donc de l'IHM et donc ne justifie pas un passage vers une couche métier et, sauf cas particulier comme de la customisation de comportement par settings utilisateurs, etc..., devrait être traité le plus simplement du monde, dans le formulaire.

            P.S.: Bon, après, les sombres bidouilles du Designer de VB.NET, c'est aussi implémentable en C# (soi-même), à base d'un champ statique dans une classe dérivée de Form et d'un constructeur de cette classe qui tripatouille ce champ en lousdé, mais c'est de la très sale bidouille made in VB des années 90.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              5 mars 2019 à 14:28:59

              Merci pour ta réponse Paul,

              Mon programme est bien entendu un peu plus complexe qu'un simple masquage de colonne de DGV ceci était juste un exemple et je comprends tout à fait que ce code relève de la couche IHM et ne justifie pas un passage vers la couche métier, en fait j'ai de nombreuses requête SQL qui interviennent dans mon formulaire (je ne fais pas de Binding) et pour moi ces requêtes n'ont pas leur place dans un formulaire je préférerai les "planquer" dans des méthodes proprement nommées ailleurs que dans mon formulaire et pouvoir appeler ces méthodes dans mes événements (click bouton, load etc..)

              Peux tu m'orienter d'un point de vue architecture sur ce qui est le plus pertinent?

              Merci du temps que vous m'accordez 

              • Partager sur Facebook
              • Partager sur Twitter
              Ce n'est pas en voulant améliorer la bougie que l'on a découvert l'électricité
                5 mars 2019 à 16:35:00

                Ok, c'est un cas des plus courant.

                Pour ce genre d'application, on a tendance à bien séparer la partie chargement/sauvegarde des données dans une couche sous la couche métier : la couche data.

                IHM --> Métier --> Data

                Donc, l'IHM ne demande rien directement à la couche Data.

                On peut faire une exception si l'on fait une application type PhpMyAdmin, etc..., ou la couche métier n'existe pas à proprement dit.

                Comme les sources de données est l'une des choses qui change le plus dans un projet, c'est le genre de chose qu'on isole au maximum.

                Pour l'isolation, vous pouvez vous servir d'outils comme un ORM (Entity Framework, NHibernate, etc...) qui seront en charge de mapper dans des objets DTO les données des bases.

                Vous pouvez aussi faire de l'isolation en l'utilisant des procédures stockées à la place de requêtes en dur.

                En résumé, faites le maximum pour que ces requêtes ne soient pas dans votre code, ou dans une partie extrêmement restreinte de votre code, car c'est une partie qui change tout le temps.

                Donc, en résumé, le code d'IHM n'y connait rien en terme de données autres que celles fournit par la couche métier. La modélisation des données de la présentation, des données utilisées par outils métiers pour y appliquer les règles et traitement métier, et les données sous forme de table chargeable/sauvable n'ont pas grand-chose à voir.

                Donc, votre couche présentation appelle des méthodes de la couche métiers correspondant à l'API que fournit la couche métier à la couche Présentation. Les données retournées par cette API sont les informations que l'IHM doit afficher comme elle veut. Elle n'a pas à savoir comment ces données sont "calculées".

                La couche métier utilise en interne des classes adaptées à ces traitements internes et utilise la couche data pour les remplir depuis des données fournies par la couche métier.

                Si vous n'utilisez pas d'ORM, les data de la couche data sont données sous forme de tables, donc généralement complètement inutilisable pour appliquer des règles métier un tant soit peu non trivial.

                Si vous utilisez un ORM, les data qu'il fournit sont généralement plus riches en terme Objet, rendant la séparation entre la couche data et la couche métier mon strict. En clair, avec un ORM, on peut intégrer l'ORM dans la couche métier plutôt que de faire une couche à part, si les data sortie d'ORM sont utilisable par les règles métier.

                C'est de l'architecture de solution "de base", cela n'a pas grand-chose à voir avec la question initiale.

                Votre question initiale est plus sur "comment dialoguer entre les couches".

                Il y a plusieurs manière de faire, mais il faut toujours préserver l’indépendance des couches, en utilisant des objets type DTO par exemple (un DataSet avec que des données pertinentes, sans comportement, en n'est un exemple).

                Le dataBinding est aussi une solution, particulièrement élégante.

                • Partager sur Facebook
                • Partager sur Twitter
                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                appeler un objet d'une classe dans une autre C#

                × 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