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 :

Fonction de remplissage de contrôles


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Par défaut Fonction de remplissage de contrôles
    Bonjour

    Suite à ce topic (filtrage-multi-critere-dataviews-plusieurs-evenements) où on m'avait donné des éléments de réponse pour construire une fonction de remplissage, je cherche à optimiser les 2 boucles qui ont un inconvénient visuel (effet sapin de Noël clignotement des contrôles).
    Le code du topic précédent a donc reçu quelques optimisations grâce aux conseils du cours de P.Lasserre :
    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
        Private Sub UpdateEquipList(ByVal flpanel1 As FlowLayoutPanel, Optional ByVal flpanel2 As FlowLayoutPanel = Nothing, Optional ByVal flpanel3 As FlowLayoutPanel = Nothing, Optional ByVal Setup As String = "", Optional ByVal RowFilter As String = "")
            Dim dv As DataView
            Dim NeededDataTables As String() = {"Food", "Weapon", "Ranged", "Ammo", "Head", "Neck", "Ear", "Ring", "Hands", "Body", "Legs", "Feet", "Waist", "Back", "WStable"}
            If {"", "1", "2"}.Contains(Setup) AndAlso flpanel1 IsNot Nothing Then
                For Each flpanel As FlowLayoutPanel In New Control() {flpanel1, flpanel2, flpanel3}
                    For Each dt As DataTable In Me.DataSet.Tables
                        If NeededDataTables.Contains(dt.TableName) Then
                            For Each Cbx As ComboBox In flpanel.Controls.OfType(Of ComboBox)().Where(Function(Cbx) Cbx.Name.Contains(dt.TableName))
                                If Setup = "" OrElse Cbx.Name.Contains(Setup) Then
    
                                    dv = New DataView(dt)
                                    dv.RowFilter = RowFilter
                                    dv.RowStateFilter = DataViewRowState.CurrentRows
                                    dv.ApplyDefaultSort = True
                                    Cbx.DataSource = dv
                                    Cbx.DisplayMember = "Names"
    
                                End If
                            Next
                        End If
                    Next
                Next
            End If
        End Sub
    En français ce code signifie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Fonction UpdateEquipList de Paramètres(Conteneur(s)?, Tous les controles ou juste une partie ?, expression de filtrage)
    Pour chaque Conteneur spécifié dans Paramètres
         Pour chaque DataTable importée (liste préfiltrée)
              Pour chaque contrôle dans le conteneur en cours ET dont le nom contient le nom de la DataTable en cours
              Faire
              ...
              Controle.Datasource = Dataview filtrée avec Expression spécifiée dans Paramètres
              ...
              Suivant
         Suivant
    Suivant
    Sur mon interface j'ai 3 conteneurs de type flowlayoutpanel, chacun contenant 2 à 30 comboboxs et certains ont 2 listboxs. Les listboxs je les remplis "à la main" ailleurs... donc là ma fonction ne se préoccupe que des comboboxs.

    Dans ce code j'ai réussi à limiter le nombre de bouclages de la 1ère boucle grâce à une liste de strings. Par contre pour la 2e boucle...

    Mon problème concerne en particulier les lignes en gras, càd que je n'arrive pas à construire une [liste de contrôles] sans que VB2010 me foute une erreur de syntaxe ou une exception d'Argument à l'execution...
    En fait j'essaie d'adapter l'exemple de Krosoft sur MSDN...
    L'erreur affichée par VB pour la syntaxe du code ci-dessus est :
    "Le paramètre lambda 'Cbx' masque une variable dans un bloc englobant, une variable de portée précédemment définie ou une variable déclarée implicitement dans une expression de requête."
    Si quelqu'un peut m'aider à communiquer correctement avec VB, ce serait svp.
    Les suggestions d'implémentation sont aussi les bienvenues ^^

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    je ne sais pas qui t'as conseillé ce code mais il est illisible ; des sous méthodes ou du linq aideraient à la lisibilité

    sinon ton erreur vient de là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     For Each Cbx As ComboBox In flpanel.Controls.OfType(Of  ComboBox)().Where(Function(Cbx) Cbx.Name.Contains(dt.TableName))

    for each cbx déclare une variable cbx puis tu dis function (cbx) qui en déclare une autre du meme nom

    =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For Each Cbx As ComboBox In flpanel.Controls.OfType(Of  ComboBox)().Where(Function(Cbx2) Cbx2.Name.Contains(dt.TableName))

    edit : je détaille comment rendre ce genre de chose plus lisible, pas forcément calqué sur ton cas mais sub des boucles et sous boucles :

    à la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for a 
      for b
        for c
        traitmement sur c

    tu peux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sub départ
      for a
         traitementsurtypedea(a)
     
    sub traitementsurtypedea(a)
      for b
         traitementsurtypedeb(b)
     
    sub traitmentsurtypedeb(b)
      traitement sur c
    comme ca les boucles sont vides et une sub contient le code du traitement

    et en linq ca doit donner un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from a in listedeA from b in a.listedeB from c in listedeC where condition sur c.for each (addressof traitementsurtypedeC)(c)
    donc une ligne et une sub
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Par défaut
    Comment ça illisible ? Aurais-tu une meilleure idée que 2 simples boucles ForEach imbriquées ?
    Je suis débutant, je ne sait pas ce que tu veux dire par "sous-méthodes", où ca dans le code il y en aurait besoin ? Idem pour Linq, jamais utilisé

    Quant à l'erreur j'ai fait ce que tu m'as dit cela enlève l'erreur mais rajoute un avertissement
    l'utilisation de la variable d'itération dt peut provoquer des résultats inattendus...
    Je l'ai ignoré et lancé le déboguage et là VLAN! InvalidOperationException
    Je reçois la même Exception si je remplace la var dt par dt2 ou CurrentDT=New Datatable(dt.tablename)...

    Le pire est que d'habitude quand une exception est levée VB2010 me pointe automatiquement où elle se trouve en la surlignant. Là rien du tout, écran blanc... Donc je ne vois pas ce qui provoque réellement cette exception ??

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    pour l'avertissement ca vient de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    flpanel.Controls.OfType(Of ComboBox)().Where(Function(Cbx) Cbx.Name.Contains(dt.TableName))

    c'est du linq et linq n'aime pas qu'on lui fasse manipuler des variables qui proviennent d'un for each

    il faut faire juste avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dim dt2 as datatable = dt
    et mettre dt2 dans l'expression linq

    en espérant que ca retire l'exception au passage (surment le cas car je crois que les exception dans du linq ne font pas pointer vers la ligne)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Par défaut
    Bonjour Pol63 et merci pour tes réponses

    Nos posts ont du se croiser hier soir, mais le probleme du dt2 ne leve toujours pas l'InvalidArgumentException... (plus d'avertissement par contre)

    J'ai passé 1heure a decortiquer la fenetre InvalidArgumentException pour "essayer" de savoir quelle foutue ligne de code ma faisait planter... rien trouvé... Pourtant il me parle de mettre un "New" pour instancier un objet quelquepart...

    Bon jme suis dit o point j'en suis... autant m'essayer au linq comme tu me l'as laissé entendre dans ton post. Il y a en effet un chapitre dessus dans le cours de P.Lasserre, et tous ses exemples utilisent clairement un language de requete avec au minimum les instructions FROM et In.
    En passant, mon code n'ayant pas de FROM du tout, je vois pas à quoi tu lui trouve une ressemblance même lointaine à du Linq ?
    Je me tente donc a réécrire 2 des 3 boucles précédentes "correctement" en suivant tes conseils (faire sauter b et c en une seule boucle) et la syntaxe du cours Lasserre, ce qui donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        Private Sub UpdateEquipList(ByVal flpanel1 As FlowLayoutPanel, Optional ByVal flpanel2 As FlowLayoutPanel = Nothing, Optional ByVal flpanel3 As FlowLayoutPanel = Nothing, Optional ByVal Setup As String = "", Optional ByVal RowFilter As String = "")
            Dim dv As DataView
            Dim NeededDataTables As String() = {"Food", "Weapon", "Ranged", "Ammo", "Head", "Neck", "Ear", "Ring", "Hands", "Body", "Legs", "Feet", "Waist", "Back", "WStable"}
            Dim OriginalRowFilter As String = RowFilter
            Dim MutualExCbxName, MutualExCbxText As String
            If {"", "1", "2"}.Contains(Setup) AndAlso flpanel1 IsNot Nothing Then
                For Each flpanel As FlowLayoutPanel In New Control() {flpanel1, flpanel2, flpanel3}
                    Dim dt2 As DataTable
                    Dim ComboboxList As Control() = From Cbx2 In flpanel.Controls.OfType(Of ComboBox)() Where Cbx2.Name.Contains( _
                                                    (From dt2 In Me.DataSet.Tables Where NeededDataTables.Contains(dt2.TableName)).TableName)
                    For Each Cbx As ComboBox In ComboboxList
    Je n'ai pas tenter de déboguer car il y a encore une erreur sur le dt2, malgré tes conseils VB n'aime toujours pas...
    L'erreur est :
    "La variable de portée 'dt2' masque une variable dans un bloc englobant ou une variable de portée précédemment définie dans l'expression de requête."

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    ton erreur vient de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim dt2 As DataTable
    Dim ComboboxList As Control() = From Cbx2 In flpanel.Controls.OfType(Of ComboBox)() Where Cbx2.Name.Contains( _
                                                    (From dt2 In Me.DataSet.Tables Where NeededDataTables.Contains(dt2.TableName)).TableName)
    le from s'écrit au complet sous cette forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from var as type in collection
    il faut voir ca comme un dim var as type puis un for each var in collection
    si le as type n'est pas spécifié, ca équivaut à as Object
    var est donc une variable déclarée pour le bloc from, utilisé par linq pour parcourir la collection

    tu te retrouves donc avec 2 variables dt2 au meme moment


    je vais regarder ton code un peu plus en détail pour comprendre ce que tu veux faire et voir si ca peut s'écrire autrement


    et pour info linq ce n'est pas seulement basé sur from, linq est un langage fonctionnel au sein de .net
    fonctionnel veut dire qu'on décrit ce qu'on veut faire sous forme de "phrase" et non de code, la compilation s'occupant de ca
    si on a une collection de control, et qu'on veut les controle ayant un a dans leur nom en linq ca donne ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    dim controlsAvecUnA as ienuerable(of control)
    controlsAvecUnA  = me.Controls.where(function ....)
    le .where c'est aussi du linq, on lui donne une fonction (anonyme ou non) et il l'exécute pour chaque membre de la collection de départ

    les méthodes/fonctions anonymes sont comme des fonction normales, sauf qu'elle n'ont pas de nom, sont écrites au sein d'un autre bloc et on peut avoir un pointeur vers elle
    en théorie ca permet de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private function sum(a as integer, b as integer) as integer
      return a+b
    end function
    en ca : (je tape direct ici, donc la syntaxe est peut etre pas exacte)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dim f as new func(of integer, integer, integer)(function (var1 as integer, var2 as integer)(a+b))
    dim result as integer = f.invoke(51,32)
    le integer, integer, integer veut dire qu'il y a 2 paramètres integer en entrée et un integer en sortie, le dernier type est le type de sortie, il peut etre seul s'il n'y a pas de paramètre d'entrée
    le (a+b) est le code de la fonction, il faut imaginer un return devant, mais qui ne s'écrit pas dans le cas d'une fonction anonyme
    ca peut parraitre inutile comme ca, mais les cas ou c'est utile c'est au cas ou on ne connait pas à l'avance quelle fonction va etre utilisée
    par exemple, une liste de nombre, un textbox de saisie de nombre et un combobox qui contient < = >
    on fait une fonction anonyme qui retourne les inférieurs de la liste par rapport au nombre, une pour les supérieurs etc...
    et selon ce que l'utilisateur choisit dans le combobox on invoke la variable fonction sur la liste


    je ne sais pas si je suis clair, mais .net est un langage très concret, qui ne laisse pas de place au hasard (contraitement à vb6 par exemple ) et qu'il faut comprendre en détail pour coder proprement et efficacement, diminuant le temps de développement et facilitant la maintenance du code
    et certaines parties nécessitent des exemples utiles pour comprendre leur utilité
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 06/03/2010, 18h07
  2. je cherche fonction de remplissage (pot de peinture)
    Par Faudel24000 dans le forum 2D
    Réponses: 12
    Dernier message: 11/08/2009, 00h07
  3. [AC-2007] Remplissage d'un contrôle en fonction du remplissage d'un autre
    Par Razorback dans le forum IHM
    Réponses: 7
    Dernier message: 19/05/2009, 09h29
  4. [Java2D]Fonction de remplissage
    Par Guybrush dans le forum 2D
    Réponses: 6
    Dernier message: 14/05/2007, 11h23
  5. Réponses: 2
    Dernier message: 19/12/2006, 12h38

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