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 :

validation de données dans un DGV


Sujet :

VB.NET

  1. #21
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonjour chrismonoye,
    Merci pour cette autre piste : je vais essayer également pour voir si on peut capturer à temps une erreur caractère à la place d'integer
    Merci encore
    Bertrand

  2. #22
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonsoir chrismonoye,
    j'ai essayé la piste DataGridView.RowValidating :
    J'ai recopié le code donné par MSDN : le fonctionnement est sensiblement identique à celui de la validation au niveau du dataSet : affichage de la localisation d'erreur (si champ null) mais la saisie d'une lettre dans une colonne integer déclenche une erreur ! ( + petit pb de comportement lors de la suppression d'un row)
    J'ai au moins appris qq tournures de code (test integer ou pas)
    A +
    Bertrand

  3. #23
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonsoir,
    Les e.quelquechose sont propre à l’évènement, à ce propos il faut que tu déclare le bon EventArgs correspondant à ton évènement sinon tu ne pourra pas l'utiliser correctement. (Ex: e As System.Data.DataColumnChangeEventArgs si tu traite l’évènement ColumnChanging).

    Un petit mot sur DataGridView.RowValidating : Si j'ai bien compris c'est de la validation au niveau contrôle. Tu peux coder dans cet évènement mais à mon avis tu va te priver de la possibilité de pouvoir "DataBinder" d'autres contrôles simple à ta source sans modifier le code. Alors que si tu code la validation dans ColumnChanging tu pourra lier n'importe quel contrôle simple a n'importe quel champs sans rajouter la moindre ligne de code.

    Mais à quel moment se produit l'erreur exactement ? avant ou après l’évènement ColumnChanging ? Si c'est après comme je le pense tu peux annuler dans cet évènement. Par contre par curiosité j'ai voulu reproduire l'erreur et bizarrement je n'ai pas d'erreur chez moi (quand je saisi des caractères dans une colonne Integer). Je suis juste bloqué dans la cellule sans possibilité de pouvoir en sortir, il s'agit probablement d'une propriété du DataGridView paramétré différemment.

    Comme promis voici ma classe (c'est du bidouillage maison qui fonctionne très bien mais je conseille de bien comprendre sont principe avant de l'utiliser).
    Elle permet d'éviter de manipuler et faire des calculs directement sur les Champs des DataRow, évite les erreurs liées aux champs DBNUll et plus encore.....

    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    Class clsVarTypeDB(Of T)
        Private _Type As Type
        Private _TypeCode As TypeCode
        Private O_Original As Object
        Private T_Defaut As T
        Private T_Current As T
        Private bol_RequestToDBNull As Boolean
        Private _InizializeComponent As Boolean
        'Public Sub New(ByVal Value As Object, Optional ByVal Defaut As T = Nothing)
        '    SetVersioningValues(Value, Defaut)
        'End Sub
        Public Sub New()
     
        End Sub
        Public Sub New(ByVal Row As DataRow, ByVal ColName As String, Optional ByVal Defaut As T = Nothing)
            InitializeValues(Row, ColName, Defaut)
        End Sub
        Public ReadOnly Property Original() As Object
            Get
                'If _InizializeComponent = False Then Throw New Exception("L'objet n'à pas été initialisé") : Exit Property
                Return O_Original
            End Get
        End Property
        Public ReadOnly Property Defaut() As T
            Get
                'If _InizializeComponent = False Then Throw New Exception("L'objet n'à pas été initialisé") : Exit Property
                Return T_Defaut
            End Get
        End Property
        Public Property Current() As T
            Get
                'If _InizializeComponent = False Then Throw New Exception("L'objet n'à pas été initialisé") : Exit Property
                Return T_Current
            End Get
            Set(value As T)
                'If value Is Nothing Then Throw New Exception("La version Current ne peut pas etre Nothing") : Exit Property
                T_Current = value
            End Set
        End Property
        Public ReadOnly Property IsRequestToDBNull() As Boolean
            Get
                Return bol_RequestToDBNull
            End Get
            'Set(value As Boolean)
            '    _SetNothing = value
            'End Set
        End Property
        Public Sub SetRequestToDBNull()
            bol_RequestToDBNull = True
        End Sub
        Public Sub ResetRequestToDBNull()
            bol_RequestToDBNull = False
        End Sub
        Public Sub InitializeValues(ByVal Row As DataRow, ByVal ColName As String, Optional ByVal Defaut As T = Nothing)
            bol_RequestToDBNull = False
            _InizializeComponent = True
            _Type = GetType(T)
            _TypeCode = Type.GetTypeCode(GetType(T))
     
            Dim O_Value As Object = Row(ColName)
            Dim _Value As T
     
            If O_Value Is DBNull.Value Then
                _Value = Nothing
            Else
                _Value = CType(O_Value, T)
            End If
     
            If _TypeCode = TypeCode.String Then 'Le type String est un Type réference qui peut prendre la valeur Nothing. Il faut convertir la valeur Nothing en "".
                If Defaut Is Nothing Then T_Defaut = CType(Convert.ChangeType("", _Type), T)
                If _Value Is Nothing Then _Value = CType(Convert.ChangeType("", _Type), T)
            Else
                T_Defaut = Defaut
            End If
     
            If O_Value Is DBNull.Value Then
                O_Original = Nothing
                T_Current = T_Defaut
            Else
                O_Original = _Value
                T_Current = _Value
            End If
        End Sub
        Public Sub WriteValue(ByVal Row As DataRow, ByVal ColName As String, Optional ByVal WriteDefaut As Boolean = False)
            If _InizializeComponent = False Then Throw New Exception("L'objet n'à pas été initialisé") : Exit Sub
            Dim _Value As T
            If bol_RequestToDBNull = True Then
                If WriteDefaut = True Then
                    _Value = T_Defaut
                Else
                    If O_Original Is Nothing Then
                        Exit Sub
                    Else
                        Row(ColName) = DBNull.Value
                        Exit Sub
                    End If
                End If
            Else
                _Value = Current
            End If
     
            If O_Original Is Nothing Then
                Row(ColName) = _Value
            Else
                Dim T_Original As T = CType(O_Original, T)
                If T_Original.Equals(_Value) Then
                Else
                    Row(ColName) = _Value
                End If
            End If
        End Sub
    End Class
    Pour l'utiliser :
    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
    ' L’objet doit absolument être initialisé à partir de la DataRow avant d'être utilisé :
    ' - Soit au moment de sa construction :
    Dim MyVar1 As New clsVarTypeDB(Of String)(Row, "ColumnName")
    ' - Soit après :
    Dim MyVar1 As clsVarTypeDB(Of String)
    MyVar1.InitializeValues(Row, "ColumnName")
    ' - On peux aussi déclarer un valeur par défaut utilisé dans Current si la valeur Originale est égale à DBNull :
    Dim MyVar1 As New clsVarTypeDB(Of String)(Row, "ColumnName", DéfautValue)
     
    ' - Puis on peux l'utiliser comme n'importe quel variable :
    MyVar1.Current = "NewValue"
    ' - Quand on a fini de travailler avec les variables on écrit dans la Datarow passé en paramètre : (En réalité ça écrit que si c'est nécessaire pour ne pas modifier la propriété HasChanges du DataSet inutilement.
    MyVar1.WriteValue(Row, TableTaches.STATUT)
     
    ' Si on veux écrire une valeur DBNull, c'est possible :
    MyVar1.SetRequestToDBNull()
    ' Penser à faire un reset sinon ça va écrire systématiquement des DBNull :
    MyVar1.ResetRequestToDBNull()
    Noter que j'ai reproduit le même comportement que les variables standard du Framework (Types Référence et Types Valeur) :
    - la variable "Originale" est l'équivalent d'une variable type Réference (Les String et les Object sont des Types Références qui peuvent prendre la valeur Nothing)
    - Les variables "Current" et "Défaut" sont l'équivalent d'une variable type Valeur (Les Integer, Single, Boolean....etc sont des Types Valeurs, ils ne prennent pas la valeur Nothing)

  4. #24
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonsoir,
    "Chez moi" l'erreur se produit dès que je clique en dehors de la cellule attendant un Integer (voir ci joint)
    Quant à savoir si cela intervient ou pas après un ColumnChanging il faudrait d'abord que je puisse capturer cet événement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Private Sub EventTableColumnChanging(sender As System.Object, e As System.Data.DataColumnChangeEventArgs)
    je ne trouve pas de ColumnChanging comme handles
    y a t il une déclaration spécifique à faire avant ?
    (faut vraiment que je potasse les événements)
    Pour la classe, merci bcp, je vais y regarder "tout doucement" à mon rythme (faut que je mette le décodeur) pour essayer d'en comprendre l'utilisation
    Merci encore
    Bertrand
    Images attachées Images attachées  

  5. #25
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Pour les évènements tu peux t'abonner directement depuis l'éditeur de code de VB (tu sélectionne ton contrôle puis tu sélectionne ton évènement),
    sinon il y a encore mieux : Tu peux déclarer un évènement dans le Constructeur de ta Form ou dans le Load (Derriere AdressOf tu mets le nom de ta procédure qui va traiter l’évènement sans oublié de préciser le bon argument xxxxxEventArgs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Private Sub Form_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Dim MyDataTable as DataTable = MonDataSet.Tables("MaTable")
    AddHandler MyDataTable.ColumnChanging, AddressOf EventTableColumnChanging
    End Sub
     
    Private Sub EventTableColumnChanging (sender As System.Object, e As System.Data.DataColumnChangeEventArgs)
    .....
    End Sub
    Pour ton erreur la solution est marqué dans ta capture d'écran :
    Pour remplacer cette boite de Dialogue par défaut, traiter l'évenement DataError
    Tu fait comme pour le premier évènement avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AddHandler DataGridView1.DataError, AddressOf EventDataGridViewDataError
    Tu doit pouvoir modifier la valeur de ta cellule et mettre une valeur valide je pense, Par contre j'ai un doute sur la valeur de e.context . Vois sur Msdn :
    http://msdn.microsoft.com/fr-fr/libr...(v=vs.80).aspx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Private Sub EventDatagridViewDataError(ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs)
    Dim ColName As String = DataGridView1.Columns(e.ColumnIndex).Name
    Dim Cell As DataGridViewCell = DataGridView1(e.ColumnIndex, e.RowIndex)
          If (e.Context = 3) Then
               If ColName = "MaColonneInteger" Then
                    Cell.Value=Nothing
               End If
          End If
    End Sub

  6. #26
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Merci encore,
    faudra vraiment que je travaille cette notion d'événement
    Je n'avais effectivement pas déclaré de dataTable, le DGV étant chargé par le Dataset
    J'ai viré tous les tests pour ne laisser que la détection du DataGridView1.DataError
    Par contre, je n'ai pas compris le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          If (e.Context = 3) Then
    Je l'ai donc fait précéder de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      MessageBox.Show("Erreur survenue " & e.Context.ToString())
    A la place de l'integer, si je saisis
    1) vide :
    rien ne se passe, jusqu'à la tentative de sauvegarde qui déclenche une erreur
    2) une ou plusieurs lettre(s) :
    mon msgbox indique : Erreur survenue, Parsing, Commit
    on ne peut pas quitter la cellule tant qu'on n'a pas remplacé les lettres par un chiffre ou vide
    la cellule ne s'affiche pas donc à priori e.Context <> 3

    Merci encore de ta patience (et il en faut avec certains comme moi !!)
    a+
    Bertrand

  7. #27
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    En fait dans mon programme perso je n'ai rien mis dans la procédure DataError, Le simple fait de déclarer l’évènement suffit à faire disparaître la fenêtre de message d'erreur.

    As tu toujours le message d'erreur dans ton cas ?
    Quand au e.context = 3 je ne sais plus à quoi ça correspond, j'avais tâtonné aussi un peu comme toi mais mon code ne l'utilise plus.

    Quand à l'erreur au moment de la sauvegarde, est tu sûre que c'est la cause de l'erreur est la même ?

    pas de soucis pour la patience

  8. #28
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonjour,
    Le message d'erreur précédemment reproduit n'apparait plus

    dans le champ integer

    1) si je saisis une lettre, il ne se passe rien tant que je ne sauvegarde pas le dataset, à ce moment là j'ai la row en question signalée et rouge et le message ci joint
    N'ayant plus aucun test sur le champ, je suppose que ce message est généré car j'ai défini cette variable à non nullable dans le TableAdapter

    2) si je saisis un lettre
    j'ai ma msgbox erreur .. parsing, commit
    mais le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     If (e.Context = 3) Then
    n'est jamais validé, j'ai également essayé sans plus de résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If (e.Context = DataGridViewDataErrorContexts.Commit) Or (e.Context = DataGridViewDataErrorContexts.Parsing) Then
    J'ai alors supprimé ce test
    même comportement en cas de saisie de lettre, sauf si on force un enregistrement et dans ce cas la cellule est bien forcée (et enregistrée) à la valeur désirée
    A+
    Bertrand
    Images attachées Images attachées  

  9. #29
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonsoir Bertand,
    Bon apparemment si j'ai bien compris tu as déjà réglé un premier problème en utilisant l’évènement DataError. (Oublie les e.context, apparemment il n'y a pas besoin de traiter l'erreur, une simple déclaration de l’évènement DataError suffit).
    Il reste plus qu'a régler l'erreur au moment de la sauvegarde.
    J'ai pas compris ou tu avais paramétré ta donnée à non nullable, je suppose que tu veux parler de ta base de données.
    Comme je disais quelques post plus haut, a mon avis c'est un choix a faire :
    - Tu peux interdire les valeurs DBNull dans ta base mais dans ce cas tu dois t’assurer que ton code ou un utilisateur ne pourra pas introduire de valeur Null.
    - Pour ma part j'ai fait le choix inverse, j'autorise les valeurs DBNull, de cette façon j'ai moins de contraintes par rapport à la base mais je dois faire un test systématique de toutes les variables dans le code pour tester les DBNull. C'est là que ma classe intervient, elle se charge de convertir les DBNull et comme ca j'ai plus de problèmes.

  10. #30
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonsoir BasicZX81,
    Certains champs (mais pas la majorité) dans ma BDD (Access et SQL Server) sont "non nullable" car ils servent de clé étrangère, ou de critère de tri par exemple.
    J'ai viré le test sur le e.context, j'affiche seulement un message dans ma statusBox et on ne peut pas sortir du champ sans mettre un integer ou vide : ce pb est à priori résolu !

    J'ai fait un autre essai : le Form ayant été crée via l'assistant graphique (dataAdapter, dataBindingsource,,.) , j'ai mis la propriété "AllowDBNull" à false dans la vue Dataset. Maintenant, si je saisis 'vide' ds la champ integer, il me supprime toute la ligne dés que je clique en dehors de celle ci : expéditif mais efficace (cela ressemble à du test par row) !
    Si tu n'y vois pas d'inconvénient, j'aimerais me faire et te soumettre un résumé de tout ce fil pour voir si j'ai bien compris !
    PS hors sujet : ton appli est programmée sous formes de classes, ou à l'aide de l’assistant graphique, ou un mélange des 2 ?
    a+
    Bertrand

  11. #31
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonsoir, c'est ok pour le résumé pas de soucis si je peux t'aider mais il faudra être indulgent j'ai pas forcement toutes les réponses
    Pour AllowDBNull je ne m'en suis jamais servie, il faudra que je teste si j'ai l'occasion.
    Concernant mon appli j'ai presque tout fait avec du code notamment la construction du DataSet. Je ne suis pas sûre d'avoir fait le bon choix mais ça ne change pas grand chose au final. Tout ce qu'on peut faire en mode Design, on peut le faire par le code et vis versa.

  12. #32
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonsoir,
    Pour me faire un résumé clair des différentes solutions, j'ai fait quelques recherches sur les événements et j'ai parcouru d'autres tutoriaux.
    De ce fait, j'ai encore plus de questions qu'avant
    Merci de me commenter ce que j'ai cru comprendre de la solution préconisée par MSDN (Validation au niveau du DataSet):
    http://msdn.microsoft.com/en-us/vstudio/bb643821

    Dans la vidéo MSDN sont utilisés les événements :
    MaDataTable_ColumnChanged et MaDataTable_TableNewRow
    La validation est testée pour chacun des ces 2 événements

    Dans un autre tutorial (AppDev Learning) sont utilisés :

    MaDataTable_ColumnChanging :
    Si critère de validité ne concerne qu’une colonne (exple : vide, integer,,..) => MaTableRow.SetColumnError(NomColumn, “message”)
    => MaTableRow.SetColumnError(NomColumn, “”)

    MaDataTable_RowChanging :
    Si critère de validité concerne plusieurs colonnes de la row (exple : prix > xx et Qté < yy)
    => e.Row.RowError
    => e.Row.ClearErrors

    MaDataTable_TableNewRow :
    utilisé pour forcer les valeurs par défaut (ça je le fais graphiquement dans les propriétés de chaque champ de la datatable)

    Questions :
    Vaut il mieux utiliser ColumnChanged ou ColumnChanging ?
    La validation sur TableNewRow comme le fait MSDN est elle nécessaire ?
    J’ai trouvé également cet extrait de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If e.Row.RowState <> DataRowState.Deleted Then
    Je suppose qu’il permet de ne pas tester une ligne déjà supprimée ?


    Avantages :
    Tous les controls et formulaires liés à cette DataTable sont automatiquement testés (protégés) sans code à ajouter sauf celui de la gestion de l'erreur
    Des règles de validation peuvent (je pense) concerner plusieurs tables dans le même dataset
    Toutes les erreurs column/row déclenchent un MonDataset.HasErrors général

    Inconvénients :
    Les messages utilisateurs destinés à être affichés dans un control spécifique (txt_status dans le formulaire) doivent passer par une public property ?
    Le code semble lourd mais :
    - il le serait beaucoup moins si testé uniquement sur 1 événement (ColumnChanging)
    - des tests génériques (vide, entier,..) doivent pouvoir être « mutualisés P

  13. #33
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Bonsoir,
    Pour me faire un résumé clair des différentes solutions, j'ai fait quelques recherches sur les événements et j'ai parcouru d'autres tutoriaux.
    De ce fait, j'ai encore plus de questions qu'avant
    Merci de me commenter ce que j'ai cru comprendre de la solution préconisée par MSDN (Validation au niveau du DataSet):
    http://msdn.microsoft.com/en-us/vstudio/bb643821

    Dans la vidéo MSDN sont utilisés les événements :
    MaDataTable_ColumnChanged et MaDataTable_TableNewRow
    La validation est testée pour chacun des ces 2 événements

    Dans un autre tutorial (AppDev Learning) sont utilisés :

    MaDataTable_ColumnChanging :
    Si critère de validité ne concerne qu’une colonne (exple : vide, integer,,..) => MaTableRow.SetColumnError(NomColumn, “message”)
    => MaTableRow.SetColumnError(NomColumn, “”)

    MaDataTable_RowChanging :
    Si critère de validité concerne plusieurs colonnes de la row (exple : prix > xx et Qté < yy)
    => e.Row.RowError
    => e.Row.ClearErrors

    MaDataTable_TableNewRow :
    utilisé pour forcer les valeurs par défaut (ça je le fais graphiquement dans les propriétés de chaque champ de la datatable)

    Questions :
    Vaut il mieux utiliser ColumnChanged ou ColumnChanging ?
    La validation sur TableNewRow comme le fait MSDN est elle nécessaire ?

    J’ai trouvé également cet extrait de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If e.Row.RowState <> DataRowState.Deleted Then
    Je suppose qu’il permet de ne pas tester une ligne déjà supprimée ?


    Avantages :
    Tous les controls et formulaires liés à cette DataTable sont automatiquement testés (protégés) sans code à ajouter sauf celui de la gestion de l'erreur
    Des règles de validation peuvent (je pense) concerner plusieurs tables dans le même dataset
    Toutes les erreurs column/row déclenchent un MonDataset.HasErrors général

    Inconvénients :
    Les messages utilisateurs destinés à être affichés dans un control spécifique (txt_status dans le formulaire) doivent passer par une public property ?
    Le code semble lourd mais :
    - il le serait beaucoup moins si testé uniquement sur 1 événement (ColumnChanging)
    - des tests génériques (vide, entier,..) doivent pouvoir être « mutualisés

    Par avance, merci
    Bertrand

  14. #34
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonsoir, tu as fait un double post
    Je vais pas réecrire tous ce que j'ai posté mais je rajoute quelques observations par rapport à ma propre expérience personnel.
    A priori je ne vois pas trop l'intérêt de valider une ligne que tu viens d'ajouter avec NewRow mais je peux me tromper. Au moment ou tu créer ta ligne tu peux valoriser certains champs, mais je ne vois pas pourquoi ta ligne ne serait pas valide dans cet évènement.
    Pour les évènements RowChanging ou RowChanged ça peux servir su tu souhaite valider plusieurs colonnes qui doivent être modifiées simultanément pour être valide. Ça reste un cas assez rare je pense, normalement on contrôle la validité colonne par colonne et ça ne t'empêche pas de valider ta ligne selon la valeur des autres colonnes.
    Entre ColumnChanging et ColumnChanged je ne peux pas te répondre, je n'ai pas noté de différences majeurs sauf que tu ne peux pas annuler de la même façon. (Voir quelques Post plus haut).

    If e.Row.RowState <> DataRowState.Deleted Then
    Je suppose qu’il permet de ne pas tester une ligne déjà supprimée ?
    Oui mais en principe quand tu fait ta validation dans ColumnChaning, tu travaille sur ta ligne courante, autrement dit tu ne devrait pas récupérer de ligne Deleted dans cet évènement.

    Après j'ai pas compris les avantages et les inconvénients et par rapport à quoi ? Pourquoi le code semble lourd ?

  15. #35
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Re bonsoir,
    Effectivement, j'ai glissé chef !
    Le post est "parti tout seul" sans la formule de politesse finale !

    Si je résume :
    - la validation dans le NewRow n'est pas à priori utile, les colonnes pouvant être validées lors du Columnchanging
    - RowChanging/Rowchanged : si critères sur plusieurs rows simultanément

    J'ai oublié de préciser que le code faisant appel à DataRowState.Deleted était extrait d'un exemple basé sur le RowChanging, donc sur peut être plusieurs rows : donc logique

    Avantages de la validation au niveau du dataset par rapport à une validation au niveau du formulaire : si plusieurs formulaires ou contrôles ou pour source le même dataset : pas besoin de redéfinir les critères de validation à chaque formulaire

    Code trop lourd : erreur d'appréciation de ma part au vu du code MSDN qui fait apparait grosso modo 2 sub par critère de validation, mais qui n'a plus lieu d'être si on ne valorise plus le RowNew


    Je regarde les autres possibilités !
    Merci encore
    Bertrand

  16. #36
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Re
    Pour vérifier mon interrogation , j'ai supprimé le test de validation lié à l'événement NewRow
    Le comportement est complétement différent et faux:
    - avec NewRow : toute erreur est immédiatement visualisée (voire même avant : lorsqu'on clique sur ajout, le champ Libellé est par définition vide, ce qui lui est interdit)
    - sans Newrow : j'ai passé plusieurs heures à essayé d'en comprendre le comportement mais sans trop avoir compris : on peut accumuler plusieurs lignes non valides et ce sans aucune alarme tant qu'on essaie pas de sauvegarder, et puis tout d'un coup une alarme apparait, et puis plusieurs,...
    C'est comme ci le ColumnChanging n'intervenait pas dés le départ!
    Bizarre, mais à priori il faut garder le NewRow !
    Une explication ?
    Bertrand

  17. #37
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    665
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 665
    Points : 1 161
    Points
    1 161
    Par défaut
    Bonsoir,
    - RowChanging/Rowchanged : si critères sur plusieurs rows simultanément
    Si critères sur plusieurs cellules de la même ligne.
    Validating permet de contrôler ce qui demande à être valider et de jouer du e.Cantel tant que ces contrôles ne sont pas satisfaisants.
    Validated permet à partir de ce qui a été validé, d'orienter son code vers telle ou telle action.

    J'ai oublié de préciser que le code faisant appel à DataRowState.Deleted était extrait d'un exemple basé sur le RowChanging, donc sur peut être plusieurs rows : donc logique
    A priori, il s'agit de la ligne en cours.
    "ed", donc c'est validé, trop tard pour intercepter une ligne en cours de suppression.
    Exemple de contournement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
     
            DataGridView1.EndEdit()
            Dim row As DataGridViewRow = DataGridView1.CurrentRow
            'IsCurrentRowDirty : Dans ces cas (ex : le DataGridView est lié à une source de données), il évalue cette propriété au niveau de la ligne. 
            If DataGridView1.IsCurrentRowDirty Then
    IsCurrentRowDirty indique si la ligne active comporte des modifications non validées. il interceptera des états au plan de la ligne dont celui d'une suppression en cours.


    Avantages de la validation au niveau du dataset par rapport à une validation au niveau du formulaire : si plusieurs formulaires ou contrôles ou pour source le même dataset :
    pas besoin de redéfinir les critères de validation à chaque formulaire
    En l'état de ce que je connais, il n'y a pas de différence.
    Vu que c'est "bindé", travailler au niveau du dataset ou au niveau du DGV, la validation enverra les info à tous.
    à chacun sa philosophie, je préfère au niveau du DGV,

  18. #38
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonjour, ta solution semble interressante chrismonoye. Ma propre application étant terminé, je peux rapporter certaines difficultés que j'ai rencontré avec l’évènement ColumnChanging et que je n'aurais peut-âtre pas rencontré avec Validating.
    - J'ai utilisé ColumnChanging parce que ç'est l'endroit ou converge toutes les modifications sur le DataSet. Pour moi ça m'a facilité l'ajout d'autres contrôles simple (TextBox, Combobox...etc) bindés sur la même source et sans ajouter de lignes de codes supplémentaires pour la validation.
    Problème : Si la modification provient des contrôles simples et étant donné que l'annulation se fait dans le ColumnChanging on ne peux pas annuler les contrôles simples. (Les contrôles conservent leurs anciennes valeurs après l'annulation ce qui n'est pas génial). Pour contourner le problème j'ai du utiliser une autre procédure ou converge tout les évènements de validation des contrôles simple juste pour parvenir à les annuler proprement.
    - Finalement du point de vue de l'annulation c'est peut être plus simple de faire tous les tests de validation dans les évènements Validating. Ça mériterait que je fasse des essais dans mon application mais j'ai passé tellement de temps à régler ces petits détails que j'hésite un peu.

    Question : Dans le DataGridView1.CurrentRow tu récupére ta Row qui est bindé sur le DataSet ou celle du dataGridView ? (qui peut comporter des colonnes supplémentaires par rapport à celle du DataSet)

  19. #39
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2011
    Messages : 258
    Points : 126
    Points
    126
    Par défaut
    Merci encore à tous deux, j'ai de quoi cogiter !
    chrismonoye,
    En l'état de ce que je connais, il n'y a pas de différence.
    Vu que c'est "bindé", travailler au niveau du dataset ou au niveau du DGV, la validation enverra les info à tous.
    à chacun sa philosophie, je préfère au niveau du DGV,
    Merci de me confirmer si j'ai bien compris
    Admettons que j'ai un DGV1 sur un Form1, bindé sur MonDataset
    Si je mets des validations sur le DGV1, elles seront bien entendu liées au Dataset
    Mais si j'ai également un Form2, avec des controls liés au même Mondataset, les validations faites sur le Form1.DGV1 n'auront aucune utilité ??

    J'avais cru comprendre que là résidait l'utilité des validations au niveau du DataSet ?

    Bertrand

  20. #40
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Mais si j'ai également un Form2, avec des controls liés au même Mondataset, les validations faites sur le Form1.DGV1 n'auront aucune utilité ??
    C'est juste mais à priori tu ne devrait pas avoir besoin de faire les mêmes validations sur plusieurs Form ou alors il y a un problème de conception dans ton Appli. A la limite tu peux mettre une table en lecture seule sur ta Form2 si vraiment tu as besoin des informations. Il n'y a pas de règles mais personnellement je m'arrange pour que chaque Form manipule une table différente, donc je n'ai pas besoin de faire les mêmes validations d'une Form à une autre.

Discussions similaires

  1. [2.x] [Form] Validation des données dans un formulaire ?
    Par kolbek dans le forum Symfony
    Réponses: 4
    Dernier message: 11/09/2012, 12h45
  2. [Débutant] validation de données dans un formulaire
    Par marooh dans le forum C#
    Réponses: 0
    Dernier message: 04/08/2012, 03h28
  3. Réponses: 4
    Dernier message: 17/06/2012, 18h14
  4. Réponses: 2
    Dernier message: 09/06/2012, 10h26
  5. Réponses: 2
    Dernier message: 06/04/2007, 21h37

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