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 :

Effet de scintillement


Sujet :

VB.NET

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut Effet de scintillement
    Bonjour à vous Oh! grand développeur

    je sollicite votre aide pour m'aider, dans la mesure du possible, à enlever l'effet de scintillement lors d'écriture dans un listview par une opération multi-thread.

    J'ajoute une nouvelle ligne à la fin de chaque thread par délégué et j'ai un effet de sautillement ...genre, lorsque on regarde un écran d'ordinateur dans un film à la télévision, et ce, même si la ligne qui est ajouté est beaucoup plus bas que le bas de l'écran.

    je vous présente mon délégué dans l'espoir d'une solution,j'ai essayé refresh et c'est pire car je ne peut plus me déplacer sur la page.

    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
    Sub DelListVScan(ByVal msg As String)
            'Control.InvokeRequired = False <=>Appel normal du Form
            If Not ListVScan.InvokeRequired Then
                Dim MaStr() As String
                MaStr = msg.Split(";")
                Dim LVI As New ListViewItem
                LVI.UseItemStyleForSubItems = False
                LVI.Text = MaStr(0)
                LVI.SubItems.Add(MaStr(1))
                LVI.SubItems.Add(MaStr(2))
                LVI.SubItems.Add(MaStr(3))
                LVI.SubItems.Add(CDbl(MaStr(4)).ToString("F"))
                LVI.SubItems.Add(CDbl(MaStr(5)).ToString("F"))
                LVI.SubItems.Add(CDbl(MaStr(6)).ToString("F"))
                LVI.SubItems.Add(CDbl(MaStr(7)).ToString("F"))
                LVI.SubItems.Add(CDbl(MaStr(8)).ToString("F"))
                LVI.SubItems.Add(CDbl(MaStr(9)).ToString("F"))
                LVI.SubItems.Add(CDbl(MaStr(10)).ToString("F"))
                LVI.SubItems.Add(MaStr(11))
                If CDbl(MaStr(9)) < 0 Then
                    LVI.SubItems(9).BackColor = Color.Red
                    LVI.SubItems(10).BackColor = Color.Red
                End If
                If CDbl(MaStr(9)) > 0 Then
                    LVI.SubItems(9).BackColor = Color.AliceBlue
                    LVI.SubItems(10).BackColor = Color.AliceBlue
                End If
                ListVScan.Items.Add(LVI)
                'ListVScan.Refresh()
             Else
                'non Appel à delegue de Maniere Asynchrone (BeginInvoke) 
                DelRecLIstVScan = New UIOneArgSub(AddressOf DelListVScan)
                Me.BeginInvoke(DelRecLIstVScan, New Object() {msg})
            End If
    merci à l'avance

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 199
    Billets dans le blog
    1
    Par défaut
    As-tu essayé de passer la form en DoubleBuffered ?

    Ca permet souvent de corriger ce problème sans avoir rien d'autre à coder.

  3. #3
    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 : 44
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    à chaque ajout d'item le control recalcul tout et se redessine
    il doit y avoir beginupdate / endupdate ou un truc dans le genre sur le listview
    ca permet pendant l'ajout d'items que le control ne recalcule rien et attende le endupdate pour ne faire tout qu'une fois

    beaucoup de classes traitant beaucoup de données ont des méthodes similaires en général
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 199
    Billets dans le blog
    1
    Par défaut
    En même temps, si le listview est alimenté par un autre thread, j'imagine qu'il veut voir le listview se remplir petit à petit, et éventuellement pouvoir l'utiliser pendant qu'il se rempli, je me trompe ?

    Si c'est le cas, l'idée du beginupdate n'est pas bonne je pense, puisque le listview va se comporter de manière synchrone avec le thread de remplissage.

    Idem, j'avais dans l'idée de faire un SuspendLayout(), mais ça va faire perdre l'intérêt d'avoir un thread séparé.

  5. #5
    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 : 44
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    le problème vient surtout du fait qu'ajouter les lignes une par une est une mauvaise idée

    si le thread ramène 100 lignes, autant toutes les mettre en une seule fois à la fin
    s'il en ramène 1000 alors on peut appeler le délégué toutes les 100 lignes
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre chevronné
    Homme Profil pro
    Caféinomane
    Inscrit en
    Septembre 2011
    Messages
    202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Caféinomane

    Informations forums :
    Inscription : Septembre 2011
    Messages : 202
    Par défaut
    Bonjour,

    Pour se débarrasser de ce scintillement :

    Placer ce code juste avant la définition de votre "Public Class Form1" (en supposant que votre formulaire s'appelle form1):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Imports System.Reflection
     
    Public Module ExtensionMethods
     
        Public Sub DoubleBufferedLV(ByVal lv As ListView, ByVal setting As Boolean)
            Dim tlpType As Type = lv.[GetType]()
            Dim pi As PropertyInfo = tlpType.GetProperty("DoubleBuffered", BindingFlags.Instance Or BindingFlags.NonPublic)
            pi.SetValue(lv, setting, Nothing)
        End Sub
     
    End Module
    Ensuite, dans l'évènement Form1.Load(), ajouter ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            ExtensionMethods.DoubleBufferedLV(Listview1, True)
    Remplacez évidemment Listview1 par le nom de votre Listview.

  7. #7
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 199
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    le problème vient surtout du fait qu'ajouter les lignes une par une est une mauvaise idée

    si le thread ramène 100 lignes, autant toutes les mettre en une seule fois à la fin
    s'il en ramène 1000 alors on peut appeler le délégué toutes les 100 lignes
    Si c'est par exemple une liste d'email dans une boîte aux lettres, et qu'il faut 10 minutes pour charger tous les mails de la nuit car la ligne est lente, je doute fortement que l'utilisateur accepte d'attendre 10 minutes avant de pouvoir commencer à utiliser son logiciel. Y'a déjà assez de malheureux dans le monde qui utilisent Lotus Notes sans en rajouter une couche

    En revanche, on peut éventuellement les regrouper à l'aide d'un timer : genre toutes les 5 secondes, on ajoute les lignes retrouvées.

    Tout dépend en fait de la vitesse à laquelle les lignes arrivent.

    Mais je maintiens que la meilleure solution, c'est d'utiliser une listview doublebuffered.

  8. #8
    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 : 44
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    chacun maintient ce qu'il veut, mais s'il avait une ligne ajouté toutes les 10 minutes, il n'aurait pas de scintillement
    donc c'est bien qu'il en ajoute plein à la seconde mais une par une
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  9. #9
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 199
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    chacun maintiens ce qu'il veut, mais s'il avait une ligne ajouté toutes les 10 minutes, il n'aurait pas de scintillement
    donc c'est bien qu'il en ajoute plein à la seconde mais une par une
    C'est ce qu'il se passe dans Outlook, quand tu as une ligne ADSL2+ et que tu as des petits mails.
    Mais quand t'as une ligne 3G de rase campagne (donc une connexion GSM à 10 kbps) et que tu reçois de mails avec pièces attachées bah... Ca scintille beaucoup moins, mais t'aimerais pouvoir lire tes mails au fur et à mesure qu'il arrive, et ne pas attendre 3 heures que l'ensemble des spam aient fini de charger...

    Donc tout dépend du contexte. Et ce n'est pas parce que le programme est testé dans des conditions spécifiques qu'il ne sera pas utilisé dans d'autres conditions.

    Après, si c'est pour ajouter des données retrouvées dans un fichier local ou même une base de données, évidement, un ajout par lot avec un refresh à la fin est bien plus pertinent.

  10. #10
    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 : 44
    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 n'ai jamais dit le contraire mais il faut adapter sa réponse on contexte
    même si le doublebuffer corrige le scintillement ca n'est pas la méthode la plus logique


    si tu as 10 feuilles A4 à poser sur le bureau de ton voisin, tu vas pas faire 10 aller retour avec une feuille en mettant des patins à roulettes, tu vas les empiler et ne faire qu'un voyage
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Il y a une petite méprise : BeginUpdate/EndUpdate ne permettent pas en soi d'éliminer le scientillement, elles le rendent seulement plus improbable. En réduisant la durée de la mise à jour, on a davantage de chances que celle-ci se termine assez tôt pour que le rendu puisse lui-même être complété avant que le buffer ne soit présenté à l'écran. Mais il est toujours possible que, même en ajoutant un seul élément, on voit d'abord apparaître une frame ou seule une partie du nouvel élément aura été dessiné, puis une autre où tout aura bien été mis à jour.

    Donc, il faut utiliser à la fois le double buffering (pour le scintillement, afin de garantir que chaque frame affichée a été complétée) ET beginupdate/endupdate (pour les performances et afin que le formulaire ne soit repeint qu'une fois au lieu de vingt).

    Par contre j'aurais plutôt déclaré le double buffering au niveau du formulaire.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut
    merci pour vos réponses, en fait ce qui se passe c'est comme Polo63 dit
    à chaque ajout d'item le control recalcul tout et se redessine
    et la mise à jour prend en effet plusieurs minutes et comme StringBuilder le précisait j'aimerias pouvoir me servir de la LV pandant ce temps. je vais essayé vos choix de réponse et je vous reviens.

    merci

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut
    j'ai essayé le code de franticfranz et ça semble bien fonctionner, du fait, je vais tester le tout comme il faut avant de mettre un resolu sur le post.

    merci beaucoup c'est plus lisible maintenant

  14. #14
    Membre chevronné
    Homme Profil pro
    Caféinomane
    Inscrit en
    Septembre 2011
    Messages
    202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Caféinomane

    Informations forums :
    Inscription : Septembre 2011
    Messages : 202
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Par contre j'aurais plutôt déclaré le double buffering au niveau du formulaire.
    Le listview n'hérite pas de la propriété DoubleBuffered. Si bien qu'en déclarant le double buffering au niveau de la form, la form ne scintillera pas, mais les composants qui s'y trouvent, si. C'est incroyable, mais vrai...

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Par défaut
    100/100 résolu merci beaucoup

  16. #16
    Invité de passage
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 1
    Par défaut Fonctionne mais ... petit problème ^^
    Citation Envoyé par franticfranz Voir le message
    Bonjour,

    Pour se débarrasser de ce scintillement :

    Placer ce code juste avant la définition de votre "Public Class Form1" (en supposant que votre formulaire s'appelle form1):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Imports System.Reflection
     
    Public Module ExtensionMethods
     
        Public Sub DoubleBufferedLV(ByVal lv As ListView, ByVal setting As Boolean)
            Dim tlpType As Type = lv.[GetType]()
            Dim pi As PropertyInfo = tlpType.GetProperty("DoubleBuffered", BindingFlags.Instance Or BindingFlags.NonPublic)
            pi.SetValue(lv, setting, Nothing)
        End Sub
     
    End Module
    Ensuite, dans l'évènement Form1.Load(), ajouter ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            ExtensionMethods.DoubleBufferedLV(Listview1, True)
    Remplacez évidemment Listview1 par le nom de votre Listview.
    j'ai effectivement utilisé ta solution ça fonctionne , mais cette méthode empêche l'utilisation graphique du listview :'( mais ça ne clignote plus, je pense qu'on approche de quelque chose ^^.

  17. #17
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Par défaut
    Pour ce genre de truc, ça me semble plus logique de mettre en place une liste tampon qui récupère 1 à 1 tes éléments mais les transmets en lot à la liste servant pour l'affichage (piloter par un timer et/ou le nombre d'élément dans le tampon) afin de limiter les opérations de rafraichissement de l'affichage.

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

Discussions similaires

  1. Effet de scintillement et amélioration des déplacements
    Par Gobelins dans le forum Débuter
    Réponses: 10
    Dernier message: 24/01/2011, 19h21
  2. [2k3]Effet de scintillement dans un formulaire
    Par nuriel2 dans le forum IHM
    Réponses: 4
    Dernier message: 17/05/2006, 12h20
  3. Pb affichage avec un PaintBox (pour eviter scintillement)
    Par juan64 dans le forum C++Builder
    Réponses: 7
    Dernier message: 08/04/2004, 09h21
  4. [VB6][impression]Comment faire des effets sur les polices ?
    Par le.dod dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 08/11/2002, 10h31
  5. Effet Fade In / Fade Out sur une surface DirectDraw
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 08/09/2002, 17h37

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