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 :

Calcul des textbox de plusieurs Form


Sujet :

VB.NET

  1. #21
    Membre actif Avatar de stracoma
    Homme Profil pro
    Médecin
    Inscrit en
    Août 2013
    Messages
    413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Maroc

    Informations professionnelles :
    Activité : Médecin

    Informations forums :
    Inscription : Août 2013
    Messages : 413
    Points : 229
    Points
    229
    Par défaut
    Salut tout le monde. merci de votre soutien très très important.
    J'ai une petite question:
    rv26t a déclaré et initialisé f dans Form1 et Form2 en dehors de toute procédure, par contre dans Form3, il a déclaré f as Form4 mais la initialisé dans le sub ( Private Sub Button2_Click_1). Y 'a t-il une différence?
    Merci
    J'apprends la programmation pour le plaisir

  2. #22
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par stracoma Voir le message
    rv26t a déclaré et initialisé f dans Form1 et Form2 en dehors de toute procédure, par contre dans Form3, il a déclaré f as Form4 mais la initialisé dans le sub ( Private Sub Button2_Click_1). Y 'a t-il une différence?
    Oui,
    Citation Envoyé par stracoma Voir le message
    déclaré et initialisé f dans Form1 et Form2 en dehors de toute procédure
    Les instances f sont créées imédiatement (ce qui a pour effet, à la création de form1, la création des instances de form2 et form3.)
    Citation Envoyé par stracoma Voir le message
    par contre dans Form3, il a déclaré f as Form4 mais la initialisé dans le sub ( Private Sub Button2_Click_1).
    l'instance de f est créée seulement au moment ou l'on éxécute "Button2_Click_1"

    Je vois que tu suis attentivement
    La raison est que l'on ne fait pas de close de form2 et form3, par contre on fait un close de form4. [Edit](avec FormClosing et e.Cancel = True form2 et form3 ne peuvent pas être fermées)[/Edit]
    Quand on revient sur form1 on peut de nouveau accéder à form2 et form3 les instances (et leurs référeces) existe toujours. Par contre on ne peut plus accéder à l'instance de form4, il faut donc la recréer.
    C'est un choix de gestion des forms.

    Après tout dépend comment tu souhaiteras gérer, (retour par écran, retour au début, tout recommencer à zéro, conserver les saisies ou pas) cela dépendra de tes choix.
    [Edit2]J'ai fait le choix de conserver les saisies, pas l'affichage qui sera reconstruit. Les Forms s'enchaîne sous forme de boucle et permettent à l'utilisateur de revenir voir ses choix. C'est aussi dans l'optique que l'on peut rajouter des boutons "form précédant/suivant" (avec suivant dispo si validé).[/Edit]
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  3. #23
    Membre actif Avatar de stracoma
    Homme Profil pro
    Médecin
    Inscrit en
    Août 2013
    Messages
    413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Maroc

    Informations professionnelles :
    Activité : Médecin

    Informations forums :
    Inscription : Août 2013
    Messages : 413
    Points : 229
    Points
    229
    Par défaut
    Bonsoir:
    rv26t
    La raison est que l'on ne fait pas de close de form2 et form3, par contre on fait un close de form4. [Edit](avec FormClosing et e.Cancel = True form2 et form3 ne peuvent pas être fermées)[/Edit]
    Quand on revient sur form1 on peut de nouveau accéder à form2 et form3 les instances (et leurs référeces) existe toujours. Par contre on ne peut plus accéder à l'instance de form4, il faut donc la recréer.
    Dans ce cas si on veut en finir avec le programme(fermer tte les fenêtre),il suffit de fermer Form1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     Private Sub Form4_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
            Form1.Close()
        End Sub
    est ce vrai?
    J'apprends la programmation pour le plaisir

  4. #24
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    oui

    Par contre nous créons des liens entre les Form, et figeons le déroulement des enchaînements de Form. (cela n'est pas très POO puisque les objets doivent être indépendant, donc difficile d'utiliser un form ailleurs sans modif)

    Pour les rendre plus indépendants, nous pouvons utiliser un Form principal qui avec une liste de Form "question" effectuera le l'enchaînement. Les Form "question" n'auront plus aucun lien entre eux. Nous utiliserons la méthode avec le constructeur surchargé pour passer la classe de données en référence.
    Nous les afficherons dans une boucle en mode modal (qui bloque la suite jusqu'à la fermeture de la fenêtre) (possibilité d'annuler)
    Note : un formulaire n'est pas disposé sur Close lorsque on l'affiche en utilisant ShowDialog.

    Cré un Form5 et défini le comme "Formulaire de démarrage" dans les propriétés du projet.
    Ajoute un bouton annuler sur chaque form "question" avec DialogResult = Windows.Forms.DialogResult.Cancel (sauf le form résultat, c'est le dernier)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Public Class Form5
        Dim lf As List(Of Form) = New List(Of Form) 'liste des form questionnaires
        Dim CClass As Class1 = New Class1 ' implémente la classe de données (une seule fois)
        Private Sub Form5_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            ' Création de la liste des form
            lf.Add(New Form1(CClass)) ' questionnaire 1
            lf.Add(New Form2(CClass)) ' questionnaire 2
            lf.Add(New Form3(CClass)) ' questionnaire 3
            lf.Add(New Form4(CClass)) ' résultat
        End Sub
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Me.Hide()
            For Each f As Form In lf ' parcours des form
                If f.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit For ' affichage bloquant et traitement annuler
            Next
            Me.Show()
        End Sub
    End Class
    Les form sans réferences les unes aux autres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Public Class Form1
        Public Property CClass As Class1
     
        Sub New(ByRef c As Class1)
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            CClass = c
            Button2.Enabled = False
        End Sub
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Label1.Text = 0
            If Me.RadioButton1.Checked Then Me.Label1.Text = 10
            If Me.RadioButton2.Checked Then Me.Label1.Text = 20
            CClass.addit1 = CType(Me.Label1.Text, Integer)
            Button2.Enabled = True
        End Sub
     
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Close()
            DialogResult = Windows.Forms.DialogResult.OK
        End Sub
     
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            reset(Me)
        End Sub
     
        Public Sub reset(ByVal cont As Control)
            For Each RDB In cont.Controls.OfType(Of RadioButton)()
                RDB.Checked = False
            Next
            Me.Label1.Text = 0
            CClass.addit1 = 0
        End Sub
     
        Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
            DialogResult = Windows.Forms.DialogResult.Cancel
        End Sub
     
    End Class
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Public Class Form2
        Public Property CClass As Class1
     
        Sub New(ByRef c As Class1)
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            CClass = c
            Button2.Enabled = False
        End Sub
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Label1.Text = 0
            If Me.RadioButton1.Checked Then Me.Label1.Text = 10
            If Me.RadioButton2.Checked Then Me.Label1.Text = 20
            CClass.addit2 = CType(Me.Label1.Text, Integer)
            Button2.Enabled = True
        End Sub
     
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Close()
            DialogResult = Windows.Forms.DialogResult.OK
        End Sub
     
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            reset(Me)
        End Sub
     
        Public Sub reset(ByVal cont As Control)
            For Each RDB In cont.Controls.OfType(Of RadioButton)()
                RDB.Checked = False
            Next
            Me.Label1.Text = 0
            CClass.addit2 = 0
        End Sub
     
        Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
            DialogResult = Windows.Forms.DialogResult.Cancel
        End Sub
     
    End Class
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Public Class Form3
        Public Property CClass As Class1
     
        Sub New(ByRef c As Class1)
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            CClass = c
            Button2.Enabled = False
        End Sub
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Label1.Text = 0
            If Me.RadioButton1.Checked Then Me.Label1.Text = 10
            If Me.RadioButton2.Checked Then Me.Label1.Text = 20
            CClass.addit3 = CType(Me.Label1.Text, Integer)
            Button2.Enabled = True
        End Sub
     
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Close()
            DialogResult = Windows.Forms.DialogResult.OK
        End Sub
     
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            reset(Me)
        End Sub
     
        Public Sub reset(ByVal cont As Control)
            For Each RDB In cont.Controls.OfType(Of RadioButton)()
                RDB.Checked = False
            Next
            Me.Label1.Text = 0
            CClass.addit3 = 0
        End Sub
     
        Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
            DialogResult = Windows.Forms.DialogResult.Cancel
        End Sub
     
    End Class
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Public Class Form4
        Public Property CClass As Class1
     
        Sub New(ByRef c As Class1)
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            CClass = c
        End Sub
     
        Private Sub Form4_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Me.Label1.Text = CType(CClass.somme, String) & vbCrLf & CClass.Recapitulatif
        End Sub
     
    End Class
    Conclusion sur le principe : plus de dépendance entre form, à la création l'ordre d'ajout des form dans la liste est libre et ne modifie pas le comportement.
    Précision : dans l'exemple ci-dessus l'utilisation de propriété individuelle dans la classe de donnée lie l'ensemble, un dictionnaire peut rendre plus indépendant pour peu que l'on fournisse l'indice à la form.

    On va pouvoir se pencher sur l'utilisation du dictionnaire avec la classe de données. (un exemple détaillé à étudier ?)
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  5. #25
    Membre actif Avatar de stracoma
    Homme Profil pro
    Médecin
    Inscrit en
    Août 2013
    Messages
    413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Maroc

    Informations professionnelles :
    Activité : Médecin

    Informations forums :
    Inscription : Août 2013
    Messages : 413
    Points : 229
    Points
    229
    Par défaut
    Je ne sais comment remercier tous les intervenants de cette discussions, spécialement rv296t (ma bouée de sauvetage); J'ai appris bcp de choses. Pourtant, il y a un mais, chaque question résolue, ouvre la porte à d'autres difficultés. Je crois qu c'est en grande partie due au fait que j'ai à peine lu 170 pages sur les 1109 que compte le tuto de Plassere (qui m'a été recommandé par un intervenant de ce site). moi je vois les choses comme suit: Dim tuto(1000) as information. Bien-sûr comme tout cours, ce tuto est fais de manière à ce que si pour comprendre une informationX on doit d'abord connaitre l'informationY, alors indexeOf( informationX ) > indiexOf( informationY ).
    Mais moi quand je pose à discussion un petit projet, pour comprendre le cours,les intervenant expérimentés perféctionnent le projet en utilisant par exemple tuto(25), tuto(98), tuto(220) ....... dans leur code, alors que moi j'arrive à peine à tuto(30). Du coup pour comprendre tout le code je dois faire une recherche sur tuo(80), tuto(220) .... et ça pose problème quant je saute des chapitres entiers; en plus je n'avance plus dans mon tuto.
    Je le reprend donc, et quand je rencontre une épine, je crierai SOS dans ce forum
    Merci à vous tous
    J'apprends la programmation pour le plaisir

  6. #26
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Pas de souci, apprend à ton rythme.

    Je donne quand même l'info pour ceux qui suivaient

    Rien n'empèchera de revenir plus tard.
    __________________________________

    Voyons maintenant la méthode avec le dictionnaire pour les données.

    Etudions notre classe de données. (nous l'avions partiellement abordé)
    L'initialisation
    Nous définissons nos variables internes à la classe (un dictionnaire pour les réponses, et un entier pour le nombre de "Form" question)
    Nous créons 2 constructeurs : un standard (pour gérer 3 Form) et un paramètrable (pour gérer un nombre de "Form" quelconque) qui permet de redéfinir le nombre de "Form".
    Une méthode cré une instance du dictionnaire, et ajoute le nombre d'entrés adéquat pour gérer les résultats.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Public Class clsDicoReponses
     
        Private dicoReponse As Dictionary(Of Integer, Integer) ' données (clé/valeur) : Index formulaire, Nb point obtenu
        Private NbRep As Integer = 3    ' nombre de réponses paramètrable
     
        ''' <summary>Constructeur standard générant 3 réponses.</summary>
        Sub New()
            GenereDico()
        End Sub
        ''' <summary>Constructeur permettant de paramètrer le nombre de réponses souhaitées.</summary>
        ''' <param name="NbReponses">Le nombre de réponses souhaité.</param>
        Sub New(ByVal NbReponses As Integer)
            NbRep = NbReponses
            GenereDico()
        End Sub
        ' cré le dictionnaire et ajoute le nombre d'entrée.
        Private Sub GenereDico()
            dicoReponse = New Dictionary(Of Integer, Integer)
            For i As Integer = 1 To NbRep
                dicoReponse.Add(i, 0)
            Next
        End Sub
    Les accés aux données
    Une propriété permet de donner accés à un élément du dictionnaire par son index
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        ''' <summary>Une réponse accessible par sa clé (ici sous forme d'index numérique).</summary>
        ''' <remarks>Donne l'accés à un item du dictionaire par sa clé.</remarks>
        Public Property Reponse(cle As Integer) As Integer
            Get
                Return dicoReponse(cle)
            End Get
            Set(ByVal value As Integer)
                dicoReponse(cle) = value
            End Set
        End Property
    Des méthodes de traitement des résultats
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        ''' <summary>Donne le total de points obtenus dans les réponses</summary>
        ''' <returns>Le total</returns>
        Public Function Resultat() As Integer
            Dim Total As Integer = 0
            For Each rep As Integer In dicoReponse.Values
                Total += rep
            Next
            Return Total
        End Function
     
    ' ...
     
    End Class
    __________________________________

    La saisie avec un tabControl
    L'initialisation
    Nous créons une instance de notre classe de travail, et préparons les onglets pour la visu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Class Form5
        Public DicoReponses As clsDicoReponses = New clsDicoReponses
        'Public DicoReponses As clsDicoReponses = New clsDicoReponses(4)
     
        Private Sub Form5_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            For i As Integer = TabControl1.TabPages.Count - 1 To 1 Step -1
                TabControl1.TabPages.Remove(TabControl1.TabPages(i))
            Next
            'While TabControl1.TabPages.Count > 1
            '    TabControl1.TabPages.Remove(TabControl1.TabPages(1))
            'End While
        End Sub
    La validation d'une saisie (note la réponse et les points obtenus, et passe à l'onglet suivant)
    Nous factorisons par des méthodes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Private Sub btnValiderPage1_Click(sender As System.Object, e As System.EventArgs) Handles btnValiderPage1.Click
            Notereponse(rbParis.Checked, 1, 1) ' le radiobouton correspondant à la bonne réponse (s'il est coché donne True, sinon False)
            selectionnePage(TabPage2) 'passe au tabpage suivant
        End Sub
    idem pour chaque page

    Affichage des résultats
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Private Sub TabPage4_Enter(sender As System.Object, e As System.EventArgs) Handles TabPage4.Enter
            Label1.Text = String.Format("Vous avez {0} bonne(s) réponse(s)", DicoReponses.Resultat)
        End Sub
    Les méthodes.
    Passage à la page suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Sub selectionnePage(page As TabPage)
            If Not TabControl1.TabPages.Contains(page) Then TabControl1.TabPages.Add(page) ' ajoute la page si elle n'existe pas
            TabControl1.SelectedIndex = TabControl1.TabPages.IndexOf(page) ' donne le focus à cette page        
        End Sub
    note les info saisie dans la classe de données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        ''' <summary>Note la réponse dans la classe de données.</summary>
        ''' <param name="Correct">Réponse correcte (vrai/faux)</param>
        ''' <param name="NumPage">Le formulaire concerné (index)</param>
        ''' <param name="Points">Le nombre de points accordé.</param>
        Sub Notereponse(Correct As Boolean, NumPage As Integer, Points As Integer)
            If Correct Then DicoReponses.Reponse(NumPage) = Points Else DicoReponses.Reponse(NumPage) = 0 ' note la reponse
        End Sub
    Imaginons que l'on rajoute un formulaire (attention à bien faire enchaîner la page3 sur la nouvelle page et cette nouvelle page sur le résultat)
    Outre la création de la page et le traitement de son bouton, il suffit de donner le nombre de formulaire à la création de l'instance de la classe de données
    Cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Public DicoReponses As clsDicoReponses = New clsDicoReponses
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Public DicoReponses As clsDicoReponses = New clsDicoReponses(4)
    Si l'on en rajoute un autre il suffira de mettre 5 à la place de 4.
    Difficile de faire plus simple pour prendre en compte les nouvelles données.

    Imaginons que nos utilisateurs sont content et veulent une nouvelle fonctionalité : Un récapitulatif.
    On rajoute la méthode dans la classe de données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        ''' <summary>Fournit un récapitulatif des réponses (Num formulaire - Nb points). + total</summary>
        ''' <returns>Une chaîne de caractère (string) fournissant le récapitulatif</returns>
        Public Function Recapitulatif() As String
            Dim sb As StringBuilder = New StringBuilder
            For Each CleValeur As KeyValuePair(Of Integer, Integer) In dicoReponse ' parcours du dico pour exploiter un ensemble clé/valeur
                sb.AppendFormat("Dans le formulaire N°{0} vous avez obtenu {1} point(s).", CleValeur.Key, CleValeur.Value)
                sb.AppendLine()
            Next
            sb.AppendFormat("Donnant un total de {0} points.", Resultat)
            Return sb.ToString
        End Function
    Coté affichage
    Un label sur le Form de résultat (TabPage4) et cette ligne pour afficher l'info "Récap"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            Label2.Text = DicoReponses.Recapitulatif
    Rajouter des info d'affichage est très simple.

    Conclusion
    Même si au départ le fait de créer une classe de données a semblé plus complexe, nous pouvons voir plusieurs avantages :
    Le code est divisé en partie très simple et répartie par fonctionnalités.
    Les possibilités d'évolutions et de maintenances sont simplifiées.
    Grace au dictionnaire, nous n'avons plus à faire le cumul de chaque propriété (la boucle fait tout quel que soit le nombre d'élément) donc plus besoin d'intervenir sur la classe.

    code de la classe de données complet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    Imports System.Text
     
    Public Class clsDicoReponses
     
        Private dicoReponse As Dictionary(Of Integer, Integer) ' données (clé/valeur) : Index formulaire, Nb point obtenu
        Private NbRep As Integer = 3    ' nombre de réponses paramètrable
     
        ''' <summary>Constructeur standard générant 3 réponses.</summary>
        Sub New()
            GenereDico()
        End Sub
        ''' <summary>Constructeur permettant de paramètrer le nombre de réponses souhaitées.</summary>
        ''' <param name="NbReponses">Le nombre de réponses souhaité.</param>
        Sub New(ByVal NbReponses As Integer)
            NbRep = NbReponses
            GenereDico()
        End Sub
        ' cré le dictionnaire et ajoute le nombre d'entrée.
        Private Sub GenereDico()
            dicoReponse = New Dictionary(Of Integer, Integer)
            For i As Integer = 1 To NbRep
                dicoReponse.Add(i, 0)
            Next
        End Sub
     
        ''' <summary>Une réponse accessible par sa clé (ici sous forme d'index numérique).</summary>
        ''' <remarks>Donne l'accés à un item du dictionaire par sa clé.</remarks>
        Public Property Reponse(cle As Integer) As Integer
            Get
                Return dicoReponse(cle)
            End Get
            Set(ByVal value As Integer)
                dicoReponse(cle) = value
            End Set
        End Property
     
        ''' <summary>Donne le total de points obtenus dans les réponses</summary>
        ''' <returns>Le total</returns>
        Public Function Resultat() As Integer
            Dim Total As Integer = 0
            For Each rep As Integer In dicoReponse.Values
                Total += rep
            Next
            Return Total
        End Function
     
        ''' <summary>Fournit un récapitulatif des réponses (Num formulaire - Nb points). + total</summary>
        ''' <returns>Une chaîne de caractère (string) fournissant le récapitulatif</returns>
        Public Function Recapitulatif() As String
            Dim sb As StringBuilder = New StringBuilder
            For Each CleValeur As KeyValuePair(Of Integer, Integer) In dicoReponse ' parcours du dico pour exploiter un ensemble clé/valeur
                sb.AppendFormat("Dans le formulaire N°{0} vous avez obtenu {1} point(s).", CleValeur.Key, CleValeur.Value)
                sb.AppendLine()
            Next
            sb.AppendFormat("Donnant un total de {0} points.", Resultat)
            Return sb.ToString
        End Function
     
    End Class
    Code interface utilisateur complet (tabcontrol)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    Public Class Form5
        Public DicoReponses As clsDicoReponses = New clsDicoReponses
     
        Private Sub Form5_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            For i As Integer = TabControl1.TabPages.Count - 1 To 1 Step -1
                TabControl1.TabPages.Remove(TabControl1.TabPages(i))
            Next
        End Sub
     
        Private Sub btnValiderPage1_Click(sender As System.Object, e As System.EventArgs) Handles btnValiderPage1.Click
            Notereponse(rbParis.Checked, 1, 1) ' le radiobouton correspondant à la bonne réponse (s'il est coché donne True, sinon False)
            selectionnePage(TabPage2) 'passe au tabpage suivant
        End Sub
     
        Private Sub btnValiderPage2_Click(sender As System.Object, e As System.EventArgs) Handles btnValiderPage2.Click
            Notereponse(RadioButton6.Checked, 2, 1)
            selectionnePage(TabPage3)
        End Sub
     
        Private Sub btnValiderPage3_Click(sender As System.Object, e As System.EventArgs) Handles btnValiderPage3.Click
            Notereponse(RadioButton9.Checked, 3, 1)
            selectionnePage(TabPage4)
        End Sub
     
        Sub selectionnePage(page As TabPage)
            If Not TabControl1.TabPages.Contains(page) Then TabControl1.TabPages.Add(page) ' ajoute la page si elle n'existe pas
            TabControl1.SelectedIndex = TabControl1.TabPages.IndexOf(page) ' donne le focus à cette page        
        End Sub
     
        Private Sub TabPage4_Enter(sender As System.Object, e As System.EventArgs) Handles TabPage4.Enter
            Label1.Text = String.Format("Vous avez {0} bonne(s) réponse(s)", DicoReponses.Resultat)
            Label2.Text = DicoReponses.Recapitulatif
        End Sub
     
        ''' <summary>Note la réponse dans la classe de données.</summary>
        ''' <param name="Correct">Réponse correcte (vrai/faux)</param>
        ''' <param name="NumPage">Le formulaire concerné (index)</param>
        ''' <param name="Points">Le nombre de points accordé.</param>
        Sub Notereponse(Correct As Boolean, NumPage As Integer, Points As Integer)
            If Correct Then DicoReponses.Reponse(NumPage) = Points Else DicoReponses.Reponse(NumPage) = 0 ' note la reponse
        End Sub
     
    End Class
    __________________________________
    La saisie dans des "Form".

    La classe de données est inchangée.
    Les "Form" question auront une propriété qui leur indique la clé d'accés à la donnée dictionnaire (CleAccesDico)

    Lors de la création des "Form" question, on référence la classe de données et la clé d'accés au dico pour chaque "Form"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Public Class Form5
        Dim lf As List(Of Form) = New List(Of Form) 'liste des form questionnaires
        Dim DicoReponses As clsDicoReponses = New clsDicoReponses ' implémente la classe de données (une seule fois)
     
        Private Sub Form5_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            ' Création de la liste des form
            lf.Add(New Form1(DicoReponses, 1)) ' questionnaire 1, passe l'instance de la classe dico, et la clé d'accés
            lf.Add(New Form2(DicoReponses, 2)) ' questionnaire 2, idem
            lf.Add(New Form3(DicoReponses, 3)) ' questionnaire 3,  "
            lf.Add(New Form4(DicoReponses)) ' résultat
        End Sub
     
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Me.Hide()
            For Each f As Form In lf ' parcours des form
                If f.ShowDialog() = Windows.Forms.DialogResult.Cancel Then Exit For ' affichage bloquant
            Next
            Me.Show()
        End Sub
     
    End Class
    Les Form1, Form2, Form3 ont la même structure pour l'exemple.
    Les 2 propriétés et le constructeur sont identiques pour toutes, ensuite seul le fait de noter le résultat à la validation doit être du même accabit.
    Cela est fait par cette ligne DicoReponses.Reponse(CleAccesDico) = CType(ValeurANoter, Integer) (dans l'exemple c'est la valeur de Me.Label1.Text qui est un entier)
    Le reste peut être totalement différent. (Le type de question, la gestion des saisies)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    Public Class Form1
        Public Property DicoReponses As clsDicoReponses
        Public Property CleAccesDico As Integer ' pour lier avec la clé du dictionnaire
     
        Sub New(ByRef c As clsDicoReponses, cle As Integer)
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            DicoReponses = c ' référence le dico
            CleAccesDico = cle ' note la clé d'accès
            Button2.Enabled = False
        End Sub
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Label1.Text = 0
            If Me.RadioButton1.Checked Then Me.Label1.Text = 10
            If Me.RadioButton2.Checked Then Me.Label1.Text = 20
            DicoReponses.Reponse(CleAccesDico) = CType(Me.Label1.Text, Integer) ' note le résultat de la réponse, ligne nécessaire de retrouver dans chaque Form 
            Button2.Enabled = True
        End Sub
     
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Close()
            DialogResult = Windows.Forms.DialogResult.OK
        End Sub
     
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            reset(Me)
        End Sub
     
        Public Sub reset(ByVal cont As Control)
            For Each RDB In cont.Controls.OfType(Of RadioButton)()
                RDB.Checked = False
            Next
            Me.Label1.Text = 0
            DicoReponses.Reponse(CleAccesDico) = 0
        End Sub
     
        Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
            DialogResult = Windows.Forms.DialogResult.Cancel
        End Sub
     
    End Class
    Je ne met pas le code de Form2 et Form3 qui est identique et sert juste pour les tests et voir le principe.
    On peut voir q'une ligne suffit à noter l'info.
    Le form4 récapitulatif est très simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Public Class Form4
        Public Property DicoReponses As clsDicoReponses
     
        Sub New(ByRef c As clsDicoReponses)
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            DicoReponses = c
        End Sub
     
        Private Sub Form4_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Me.Label1.Text = DicoReponses.Resultat & vbCrLf & DicoReponses.Recapitulatif
        End Sub
     
    End Class
    Conclusion
    Il est ainsi possible d'avoir une batterie de form de question, de n'utiliser que celles que l'on souhaite (on pourrait les choisir à travers un fichier et même choisir l'ordre d'affichage) ce qui donne une grande souplesse d'évolution.
    Il est facile de réutiliser plusieurs form dans un autre projet (avec la classe de données)

    Le point à retenir c'est que l'on a créer des objets (ici sous forme de couple d'objets "Form-classe de données") indépendants et facilement réutilisable.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

Discussions similaires

  1. Calcul sur des cellules sur plusieurs feuilles
    Par vlksoft dans le forum Excel
    Réponses: 2
    Dernier message: 12/03/2009, 08h08
  2. Récupérer la valeur de plusieurs cel dans des textbox
    Par Mon_ami dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 27/01/2009, 09h03
  3. Calcul dans des textbox
    Par gds35 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 08/12/2008, 21h53
  4. Réponses: 3
    Dernier message: 13/04/2008, 10h52
  5. calcule somme des textbox dans un label
    Par hich24 dans le forum Général VBA
    Réponses: 5
    Dernier message: 07/02/2008, 14h55

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