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 :

Calculs et validation de données dans l'événement ColumnChanged d'un dataTable


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    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
    Par défaut Calculs et validation de données dans l'événement ColumnChanged d'un dataTable
    Bonjour à tous,
    J'ai plusieurs petits problèmes avec mon programme que je n'arrive pas du tout à résoudre malgré tout mes efforts. Je pense que ces problèmes sont fortement liés entre eux.
    Donc voilà, J'utilise une DataTable pour stocker des taches, (chaque ligne représentant une tache). Je fait un 1er calcul sur ces taches dés qu'une valeur change dans l’évènement ColumnChanged pour calculer par exemple si la tache est en retard ou terminé....etc. Ensuite je fait un 2eme calcul pour comptabiliser le nombre de tache terminé. (J'ai un contrôle CheckBoxTERMINE Bindé directement avec la table). Le mieux est que je vous montre le bout de code suivant :

    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
    Private Sub TableTachesColumnChanged(sender As System.Object, e As System.Data.DataColumnChangeEventArgs)
            Dim ColonneName As String = e.Column.ColumnName
            Dim ValeurProposed As Object = e.ProposedValue
    Call CalculLaLigne(e.Row, "ColumnChanged", ColonneName, ValeurProposed)
    BindingSourceTaches.EndEdit()
    Call CalculLeNombreDeTacheTerminé
    End Sub
     
        Private Sub CalculLaLigne(ByVal Row As DataRow, ByVal EventSource As String, Optional ByVal ColonneName As String = Nothing, Optional ByVal ValeurProposed As Object = Nothing)
    ' Cette procédure fait une lecture de la valeur Proposed ainsi que toutes les valeurs des autres colonnes. Elle peut retourner des résultats dans le DataRow ou décider de faire une annulation avec CancelEdit
    ......
    If CalculDoitêtreAnnulé = True then Row.CancelEdit
    End Sub
     
    Private Sub Call CalculLeNombreDeTacheTerminé
            Dim Table As DataTable = dtTableTaches
            Dim expression As String
            Dim sortOrder As String
            Dim foundrows() As DataRow
     
            expression = TableTaches.TERMINE & "='True'"
            sortOrder = TableTaches.ID_TACHE & " ASC"
            foundrows = Table.Select(expression, sortOrder)
            NbTachesTerminé = foundrows.Count
    End Sub
    Problème 1
    Hypothése de calcul initial : j'ai 3 taches Terminé sur 4 taches au total.
    Avec la ligne BindingSourceTaches.EndEdit() présente dans le code :
    -> Je décoche le Statut Terminé, j'obtiens NbTachesTerminé = 2. Ensuite si j'éxecute le code BindingSourceTaches.Current ("TERMINE") = True , j'obtiens NbTachesTerminé = 2
    Sans la ligne BindingSourceTaches.EndEdit() présente dans le code : (Toujours en partant de l'état initial)
    -> je décoche le Statut Terminé, j'obtiens NbTacheTerminé = 3

    Problème 2 et 3 :
    Hypothèse de calcul : MaProcédure CalculLaLigne doit décider d'invalider la modification TERMINE = True en exécutant CancelEdit.
    Donc je coche Terminé=True, CancelEdit s’exécute bien , les données dans la table on bien été annulé (TERMINE=False) mais mon contrôle (CheckBoxTERMINE) n'est pas rafraîchi malgré le Binding. Il se comporte comme si il gardait le Statut True, résultat : quand je change de ligne du DataGridView la procédure CalculLaLigne s'exécute à nouveau .
    J'aimerais que la procédure ne s'exécute qu'une seul fois (Problème 2).
    J'aimerais aussi que mon contrôle soit raffraichi après l’annulation (problème 3).
    Pour le probléme 3 : J'ai essayé BindingSourceTaches.CurrencyManager.Refresh() dans l’évènement LostFocus du CheckBoxTERMINE mais c'est pas très propre. (cela modifie la sélection de la cellule sur le DataGridView, j'aimerais plutôt agir sur le Binding du contrôle ChekBoxTERMINE (pour autant que cela soit la solution) mais je ne sais pas faire.

    Voilà, ca fait beaucoup d'un coup mais comme je disais je pense que tout les problèmes sont liées et ça fait trés longtemps que je tourne autour de ces problèmes sans trouver de solution.

    J'ai peu d'espoir d'arriver à trouver une solution qui règle tout (il faudrait que vous puissiez reproduire mon code ce qui n'est pas simple vu la taille du programme, sinon je suis prêt à donner mon programme source si quelqu'un veux bien regarder) C'est l'unique et dernier problème dans mon programme que j'ai gardé pour la fin voyant que je n'y arrivais pas et j'espère vraiment que vous pourrez m'aider.

  2. #2
    Membre éclairé
    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
    Par défaut
    Bonsoir , personne n'utilise les liaisons de données visiblement. Je continue de chercher mais si vous avez une façon de procéder pour faire ce type de calculs et de validation je suis toujours intéressé.
    En espérant que certains d'entre vous utilisent comme moi l’évènement ColumnChanged parce que je rame un peu , il me semble malgré tout que c'est le bon évènement à utiliser mais peut-être que je maîtrise mal la validation et l'annulation.

  3. #3
    Membre éclairé
    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
    Par défaut
    Bonjour, Je n'ai pas eu beaucoup de succès avec ce post . Je sais qu'il y a des développeurs confirmés sur ce forum, je tente à nouveau ma chance.
    Mon problème est peut-être lié à une mauvaise architecture de mon programme ou je ne sais quoi. Pourtant dans c'est dans les évènements ColumnChangxx que l'on peut intercepter tous les changements d'ou qu'il viennent.
    J'espère avoir une piste à mon problème ou un début de réponse.

    Merci à vous.

  4. #4
    Membre éclairé
    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
    Par défaut
    Problème 1 : résolu.
    J'utilise l’évènement ColumnChanging et j'écrase la valeur proposed si je veux annuler la modification comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub TableTachesColumnChanging(sender As System.Object, e As System.Data.DataColumnChangeEventArgs)
    e.ProposedValue = e.Row(e.Column.ColumnName)
    End Sub
    Au passage l'article sur msdn ne fonctionne pas et pourtant ce n'est pas faute d'avoir essayé. Je cite :
    Les mises à jour étant effectuées pendant les événements ColumnChanging, RowChanging et RowDeleting , vous pouvez annuler la mise à jour en levant une exception, ce qui interrompt les modifications.
    Reste les problèmes 2 et 3 : Le moins que l'on puisse dire c'est que le fonctionnement du moteur de DataBinding est plutôt obscure. le moment ou les contrôles sont mis à jours en réponse à une modification de la base de données étant inconnu.
    Si je décompose les étapes (Modifications dans le sens Control vers base de données) :
    1- L'utilisateur change la valeur du contrôle.
    2- Le moteur de Binding envoie une notification de modification à la source.
    3- Les évenements xxxxChanging sont déclenchés.
    4- Je peux annuler la modification comme ci-dessus.
    5- Les événements xxxxChanging et xxxxChanged continue et termine leur exécution.
    Entre les étapes 4 et 5 le moteur de DataBinding ne transmet pas la notification d'annulation au contrôle.

    A moins de forcer l'annulation de la valeur du contrôle du style CheckBoxTERMINE=False pendant l'étape 5 je ne vois pas comment je peux faire. Est ce que l’exécution de ces étapes dans un thread secondaire pourrait aussi régler le problème ?

    J'essaye de comprendre et j'espère que vous pourrait m'aider aussi.

  5. #5
    Membre éclairé
    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
    Par défaut
    Bonjour à tous, je ne sais pas si ça va intéresser quelqu'un mais voici mes conclusions et ma solution après m'être arraché les cheveux.

    Donc ,la seule solution que j'ai trouvé est d'utiliser une procédure spécifique intermédiaire que j'ai appelé EventFromUserControl si la modification provient d'un contrôle DataBindé.
    - Donc si la modification ne provient pas d'un contrôle DataBindé (Ex: modif. par le code ou depuis un DataGridView), on utilise ColumnChanged dans lequel on peux annuler avec e.row.CancelEdit.
    - Si la modification provient d'un contrôle DataBindé, on utilise une procédure EventFromuserControl spécialement destinée à lire chaque contrôle et capable de replacer le contrôle dans son état initial en cas d'annulation. La procédure CalculLaLigne à été transformé en Function de façon à pouvoir retourner la valeur original en cas d'annulation.


    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
    AddHandler CheckBoxVALIDEAT.Enter, AddressOf EventFromUserControl
    ' .....j'ai fait un essai avec un CheckBox mais on peux étendre le principe à tous les contrôles
     
    Private Sub EventFromUserControl (ByVal sender As Object, ByVal e As System.EventArgs)
            Dim ColonneName As String = sender.DataBindings.Item(0).BindingMemberInfo.BindingMember
            Dim ColonneValue As Object = Nothing
            Dim RowView As DataRowView = BindingSourceTaches.Current
            Dim Row As DataRow = RowView.Row
     
            ActiveAllControlesHandler(False)
     
            If TypeOf (sender) Is TextBox Then
    ...
            ElseIf TypeOf (sender) Is ComboBox Then
    ...
            ElseIf TypeOf (sender) Is CheckBox Then
                ColonneValue = sender.Checked
              End If
     
            ColonneValue = CalculLaLigne(Row, "UserControls", ColonneName, ColonneValue)
     
            If TypeOf (sender) Is TextBox Then
    ...
            ElseIf TypeOf (sender) Is ComboBox Then
    ...
            ElseIf TypeOf (sender) Is CheckBox Then
                sender.checked = ColonneValue
             End If
     
            ActiveAllControlesHandler(True)
     
    End Sub
     
        Private Function CalculLaLigne(ByVal Row As DataRow, ByVal EventSource As String, Optional ByVal ColonneName As String = Nothing, Optional ByVal ValeurProposed As Object = Nothing)
    ' Cette procédure fait une lecture de la valeur Proposed ainsi que toutes les valeurs des autres colonnes. Elle peut retourner des résultats dans le DataRow ou décider de faire une annulation avec CancelEdit
    ......
    If CalculDoitêtreAnnulé = True then
     Return Row(ColonneName) ' On retourne la valeur original
    Else
    Return ValeurProposed ' On retourne la valeur modifiée
    End Sub
    Vous pouvez remarquer que j'utilise la même procédure "CalculLaLigne" dans tous les cas quelque soit l'origine de la modification, ce qui me permet d'utiliser une seule logique et un code presque complètement indépendant des contrôles.

+ Répondre à la discussion
Cette discussion est résolue.

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. [Débutant] validation de données dans un DGV
    Par 105rn2 dans le forum VB.NET
    Réponses: 78
    Dernier message: 22/07/2012, 15h11
  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