IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Regénération des objets si le form est appelé plusieurs fois


Sujet :

VB.NET

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Points : 86
    Points
    86
    Par défaut Regénération des objets si le form est appelé plusieurs fois
    Bonjour,
    j'ai une form2 qui peut être appelée plusieurs fois par la form1.
    Dans le Sub (Load), j'ai le setup de plusieurs datatables.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            TaskListAsTable.Columns.Add("Type", GetType(String))
            TaskListAsTable.Columns.Add("Name", GetType(String))
            TaskListAsTable.PrimaryKey = New DataColumn() {TaskListAsTable.Columns("Name")}
            TaskListAsTable.Columns.Add("host", GetType(String))
            TaskListAsTable.Columns.Add("port_rest", GetType(String))
    Mon soucis est que lorsque j'appele la form2 pour la seconde fois, j'ai une erreur qui me dit que les colonnes de la table existe déjà.

    Avez-vous une idée pour "killer" cette table à chaque fois que je sors de Form2.

    Merci

    Patrick

  2. #2
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Salut,

    je vois trois possibilités :
    - dans ton load, avant d'ajouter tes colonnes, tu vides la collection (elle doit bien avoir une méthode du genre Clear),
    - dans ton load tu vérifies que tes colonnes n'existent pas déjà avant de les ajouter,
    - tu ajoutes tes colonnes dans ton constructeur, après l'appel à InitializeComponent.
    Plus je connais de langages, plus j'aime le C.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Points : 86
    Points
    86
    Par défaut
    Bonjour jopopmk,
    Humm!!! mon problème me semble insoluble pour une solution élégante.
    Bon, je fais un peu à l'arrache mais ça marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        Dim InitTable As Boolean = True
     
        Private Sub Setup_Light_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ' open du xdocument de config
            XCfgDoc = XDocument.Load(CfgFileName)
            If InitTable Then
                TaskListAsTable.Columns.Add("Type", GetType(String))
                TaskListAsTable.Columns.Add("Name", GetType(String))
                TaskListAsTable.PrimaryKey = New DataColumn() {TaskListAsTable.Columns("Name")}
                TaskListAsTable.Columns.Add("host", GetType(String))
                TaskListAsTable.Columns.Add("port_rest", GetType(String))
     
                InitTable = False
            End If
    Bon, pas très joli, mais efficace.
    Comme tu le vois, la variable InitTable passe à False lors du premier chargement, donc après les tables ne sont plus "ré-initialisées".
    Merci pour les idées.
    Patrick

  4. #4
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    De mes 3 propositions la dernière est la plus "propre", la première la plus sale. Tu as opté pour la seconde, c'est ton choix
    Plus je connais de langages, plus j'aime le C.

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Points : 86
    Points
    86
    Par défaut
    En effet, la 3eme est la plus belle.
    Mais il semble qu'il soit nécessaire d'aller "trifouiller" le fichier (.designer.vb) alors qu'il n'est pas recommandé d'y aller à la "main", juste laisser VS le modifier.
    Donc, pas forcement l'envie de déglinguer tout mon projet
    Je ferai un test sur un projet simple.
    Merci de ton aide.
    Patrick

  6. #6
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Je sais pas bien pour VB -mais ça doit être pareil- pour C# le code du designer est encapsulé dans une fonction InitializeComponent qui est effectivement dans un fichier à part (.designer.cs). Par contre l'appel à cette fonction est fait dans le constructeur, qui lui est dans ton fichier "normal". Tu peux donc caler du code juste après cet appel sans toucher à la partie auto-générée
    Plus je connais de langages, plus j'aime le C.

  7. #7
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    +1, je confirme.

    En VB, dans un formulaire, il suffit de taper : "Public sub new", tu tapes sur Entrée

    et hop apparaît tout seul :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      Public Sub New()
     
            ' This call is required by the designer.
            InitializeComponent()
     
            ' Add any initialization after the InitializeComponent() call.
     
        End Sub
    Le InitializeComponent va utiliser le Designer, ensuite on mets ce qu'on veut en dessous
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  8. #8
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    +1 avec jojopml et mactwist.

    L'événement Load n'est à utiliser que dans de rare cas. Les initialisations doivent se faire dans le constructeur.

    Mais ça veut aussi dire que pour appeler un formulaire nommé Form2 depuis un autre nommé Form1, il ne faut pas faire Form2.ShowDialog() car là on utilise une particularité (aberration?) de VB.NET qui fait que les formulaires sont instanciés "par défaut" au démarrage de l'application. A la place, il faut faire ceci dans Form1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim frm As New Form2()
    frm.ShowDialog()
    N.B. : J'ai utilisé ShowDialog mais cela pourrait être Show() aussi.
    N.B. 2 : On ne voit pas ton code d'appel donc ignore mon commentaire si tu fais déjà comme ça. C'est parfait (selon moi)
    Kropernic

  9. #9
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    L'événement Load n'est à utiliser que dans de rare cas.
    L'évènement Load se déclenche à chaque fois que l'on appel la fonction Show ou ShowDialog.
    Donc si on chache une Form et qu'on la réaffiche, ça se déclenche.
    Donc oui, l'initialisation doit se faire dans le constructeur.. par contre on peut utiliser l'évènement Load sans problème pour d'autre chose.


    Citation Envoyé par Kropernic Voir le message
    Mais ça veut aussi dire que pour appeler un formulaire nommé Form2 depuis un autre nommé Form1, il ne faut pas faire Form2.ShowDialog() car là on utilise une particularité (aberration?) de VB.NET qui fait que les formulaires sont instanciés "par défaut" au démarrage de l'application. A la place, il faut faire ceci dans Form1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim frm As New Form2()
    frm.ShowDialog()
    Pas tout suivi....
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  10. #10
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par mactwist69 Voir le message
    L'évènement Load se déclenche à chaque fois que l'on appel la fonction Show ou ShowDialog.
    Donc si on chache une Form et qu'on la réaffiche, ça se déclenche.
    Donc oui, l'initialisation doit se faire dans le constructeur.. par contre on peut utiliser l'évènement Load sans problème pour d'autre chose.
    Pour d'autres choses oui. Jusqu'à il y a peu, en bon débutant, je tapais tout dans le Load et j'ai effectivement été confronté aux même problèmes patrickvier car forcément, j'initialisais le bouzin plusieurs fois... Du coup, j'me suis documenté et depuis, je mets tout dans le constructeur et ça marche beaucoup mieux. Normal tu me diras vu que c'est la bonne manière de faire.
    Lors de ma "documentalisation" (l'action de se documenter... c'est quoi le terme?), j'ai aussi remarqué que le comportement réel et ce qui est écrit dans la doc ne concorde pas. Dans la MSDN, on peut lire ceci concernant Form.Load :
    Citation Envoyé par MSDN
    Occurs before a form is displayed for the first time.
    Or, comme Mactwist69 l'a dit, l'événement est déclenché à chaque fois que la fenêtre est montrée (avec Show ou ShowDialog). Du coup, ça pue. Du coup, je ne l'utilise presque plus (vraiment dans de rares exceptions).

    Citation Envoyé par mactwist69 Voir le message
    Pas tout suivi....
    Bin on ne voit pas comment il appelle ses formulaires donc ma remarque est inutile mais en VB.NET, tu peux faire depuis Form1 Form2.Show() sans jamais avoir déclaré Form2 dans Form1. C'est un truc à ne plus rien comprendre pour les débutants... Pour ça que je dis qu'il faut déclarer Form2 pour ensuite la montrer. Et j'ai oublié de la détruire (frm.Dispose()) après dans mon exemple...

    Maintenant si je dis des conneries, qu'on me corrige. Je dormirai moins con ce soir ^^.
    Kropernic

  11. #11
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Tu m'as mis le doute avec ton histoire de MSDN...

    Je teste donc, et il semble que la MSDN a raison (quand même). Si on fait juste Hide et Show, ça n'a pas l'air de se re-déclencher.
    Toujours d'après la MSDN, Load s’exécute quand VB instancie l'interface de la Form en mémoire.


    ma "documentalisation" -> "Mes recherches"

    Et sinon, j'ai compris ce que tu voulais dure avec Form2.Show()

    C'est le fait de créer une instance locale d'un formulaire en utilisant directement le nom de la classe sans instancié d'objet.
    Effectivement ce n'est pas très propre, mais c'est surtout rédhibitoire si on a besoin du constructeur.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  12. #12
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Voici la discussion où j'avais rencontré le problème.

    Y a un lien vers un autre forum où il est expliquer pourquoi l'event Load existe et qu'elle est la bonne manière d'initialiser les objets (dans le constructeur donc).
    Kropernic

  13. #13
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Et dans le discussion, ils confirme que si on Hide, ça ne reload pas :

    That is the correct behaviour of the Load event, each time it is loaded it is called. If you want to reuse the form and avoid the the Load event, rather than close the form you should hide it and use the show method to bring it out when needed.

    Mais de toute manière il faut par principe utiliser le constructeur pour initialiser les données.
    Pour m'a part j'avais choisi cette option il y a longtemp car cela permet d'améliorer un peu les performances d'affichage :

    Si on utilise le constructeur pour charger des données externes, faire les calculs etc... Alors à l'appel du Show, le formulaire s'affichera beaucoup plus rapidement, donc l'affichage "ne ramera pas trop".

    Contrairement à si on faisait les calculs dans le Load... Là, la fenêtre commencera à s'afficher et ça freezera le temps d'avoir finis tout ce qu'il y a dans le Load.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  14. #14
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    T'as fait le test avec ShowDialog ? ^^
    Kropernic

  15. #15
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    non, après le showDialog, c'est juste que la fenêtre est modale... Ca ne devrait pas changer, mais vérifie dans le doute.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  16. #16
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par mactwist69 Voir le message
    non, après le showDialog, c'est juste que la fenêtre est modale... Ca ne devrait pas changer, mais vérifie dans le doute.
    Moi je connais la réponse. C'est pour ça que je te pose la question (pour t'inciter à faire le test).
    Kropernic

  17. #17
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Ca ne vient pas du fait de la méthode Load... (Et non, tu ne pourras pas mettre Billou sur le grill à chaque fois)

    Ca vient du fait que DialogResult effectue un Dispose().

    Donc même si tu as l'impression de n'avoir que caché la fenêtre, à son rappel, il ré instancie tout, donc il re appel Load.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  18. #18
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par mactwist69 Voir le message
    Ca ne vient pas du fait de la méthode Load... (Et non, tu ne pourras pas mettre Billou sur le grill à chaque fois)

    Ca vient du fait que DialogResult effectue un Dispose().

    Donc même si tu as l'impression de n'avoir que caché la fenêtre, à son rappel, il ré instancie tout, donc il re appel Load.
    Tu sais ça d'où ?

    Moi je lis ceci dans la MSDN :
    When a form is displayed as a modal dialog box, clicking the Close button (the button with an X at the upper-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.Cancel. Unlike non-modal forms, the Close method is not called by the .NET Framework when the user clicks the close form button of a dialog box or sets the value of the DialogResult property. Instead the form is hidden and can be shown again without creating a new instance of the dialog box. Because a form displayed as a dialog box is hidden instead of closed, you must call the Dispose method of the form when the form is no longer needed by your application.
    (ça se trouve dans les remarques)

    Ce qui, à moins que je sois fatigué et que mon Anglais défaille, dis juste l'inverse de toi. Ou alors ce sont les gars de la MSDN qui étaient fatigué quand ils ont écrit cette page (c'est toujours possible aussi).
    Kropernic

  19. #19
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Tu lis mal en effet : La remarque ne concerne QUE le fait de fermer la fenêtre avec la croix :
    clicking the Close button
    Et dans ce cas, le close ne s'applique pas.

    Le showdialog est obligé de faire ça pour récupérer le dialogresult qui est le VRAI close
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  20. #20
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Alors j'ai rien dit ^^.

    N'empêche, je n'ai pas lu (j'avoue, j'ai lu en diagonale et pas tout) que ça faisait un dispose comme tu le dis. Mais c'est fort probablement ce qu'il se passe vu le comportement.

    Par contre, pour les débutants, c'est assez perturbant .

    Bref, je pense que patrickvier à toutes les réponses qu'il voulait et même plus pour le coup .
    Kropernic

Discussions similaires

  1. Réponses: 5
    Dernier message: 01/03/2015, 19h02
  2. Réponses: 1
    Dernier message: 03/08/2012, 15h06
  3. Accéder à des objets d'une Form à partir d'une classe
    Par kinouseb dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/01/2007, 18h07
  4. Réponses: 3
    Dernier message: 09/01/2007, 15h27
  5. Réponses: 13
    Dernier message: 09/05/2006, 16h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo