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 :

Modifier ListView dans un thread secondaire


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Novembre 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2006
    Messages : 129
    Par défaut Modifier ListView dans un thread secondaire
    Bonjour,

    Je travaille actuellement sur VB 2010 Express à créer un logiciel de données qui remplit une ListView.

    L'interrogation est cyclique dans un thread secondaire et même si le programme fonctionne la solution ne me satisfait pas. Globalement, à chaque itération de la boucle, le programme efface le contenu du ListView via un invoke.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Me.TableLecture.Invoke(New Action(Sub() Me.TableLecture.Items.Clear()))
    Et par la suite, les valeurs sont générées par la lecture.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim item As ListViewItem
    item = New ListViewItem({Id, Nom, Valeur, Unite})
     
    If Me.TableLecture.InvokeRequired Then
    Me.TableLecture.Invoke(New Action(Sub() Me.TableLecture.Items.Add(item)))
    End If
    Du coup, on obtient un effet clignotant fortement désagréable pour celui qui surveille les informations affichées (le fichier texte est généré via un programme de communication indépendant).

    Je cherche une solution pour modifier les lignes sans les effacer et gagner en lisibilité. Je pense qu'il faut passer par un Invoke ou Delegate ou les deux (je vois pas très bien la différence et je peine à trouver des tuto là dessus).

    A savoir que dans le tableau {Id, Nom, Valeur, Unite} la valeur de Nom est unique et que je cherche à modifier Valeur. Id et Unite n'ont d'importance que pour le lecteur.

    Merci d'avance pour l'attention accordé à ce message, n'hésitez pas a me demandé plus d'informations.

  2. #2
    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 : 42
    Localisation : Suisse

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

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Par défaut
    Je suis pas sur d'avoir tout compris à ta problématique mais voila mon conseille.

    Il faut créer une fonction UpdateMyListview(uneDataSource As uneCollectionQuiVabien). Cette fonction s'occupe de synchroniser les éléments de ton listview avec les info contenues dans uneDataSource. La version la plus simple étant de vider le listview puis le remplir à partir de uneDataSource. La version la plus élaborée serait d'identifier les différence entre uneDataSource et les items de Listview puis d'effectuer des opérations d'ajout, suppression et modification pour synchroniser les 2.

    Dans ton thread secondaire, tu fais un invoke sur UpdateMyListview en passant toutes les données des items en paramètre (la variable uneDataSource).

    Ainsi il n'y aura plus de clignotement sur ton affichage (si tu implémentes la version complexe de UpdateMyListview, il n'y aura même plus de problème de remise à zéro de la sélection du listview) pour autant que tu appelles de manière modérée la procédure de mise à jour !

    Bref en conclusion:

    Une seul fonction de callback (invoke) s'occupant de la mise à jour de l'affichage pour laquelle on fournit l'entier des données.

    En complément:

    Vérifier que le multithreading soit bien nécessaire en utilisant un timer avec une fonction récupérant les données + mise à jour du listview. S'il n'y a pas de freez de l'interface, c'est que le deuxième thread n'est pas nécessaire. Et si le multithread n'est pas nécessaire, faut mieux pas l'utiliser (vu que ca apporte une complexité importante pour la maintenance et le debuggage de l'application)

    Il peut exister d'autres solutions (multi threadées) plus élégantes, voir efficaces en fonction de ce que tu fais réellement avec ton programme. N'hésite pas à donner plus d'info si tu ne trouves pas ton bonheur dans ce message.

  3. #3
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    @Prologic : Le backgroundWorker permet aisément de faire ce que tu souhaites. Regardes ici : http://www.developpez.net/forums/d12...e/#post7054121

    N'hésites pas si tu as des questions, je te donnerais des explications détaillées.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    ca scintille car tu ajoutes un item, le redessin de l'interface est fait, tu ajoutes un item etc...

    il y a plusieurs solutions pour évite le scintillement

    tu peux créer tous les items dans ton thread puis à la fin de la lecture des données repasser par l'invoke et faire tous les .add d'un coup

    si la lecture des données est longue et que tu veux quand meme un remplissage au fur et à mesure, il faut soit ajouter les items 10 par 10 par exemple ou préciser que tu ne veux un rafraichissement de l'interface de temps en temps (il doit y avoir beginedit et endedit (ou beginupdate) sur le listview, entre les 2 appels il n'y a pas d'ajout visuel, ca oblige à jongler un peu avec un thread en parallèle)

    dans le 1er cas il faut aussi utiliser begin edit et end edit, ca gagne un peu de temps
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre actif
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Novembre 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Novembre 2006
    Messages : 129
    Par défaut
    Bonjour, et merci pour les réponses.

    Le second thread est necessaire pour la mise à jour de la ListView car c'est une boucle infinie (jusqu'à l'interruption demandé par l'utilisateur).

    Globalement, j'ai besoin d'un Invoke sur un Subitems(i), mais forcément c'est pas simple. Le plus facile serait de déclarer la ListView comme appartenant au second thread, ce qui me permettrait toutes les modifications de manière beaucoup plus simple, mais malheureusement je ne pense pas que ce soit possible.

    @sinople : il me semblait qu'il n'était pas possible de passer des paramètres via un invoke ?

    @pol63 : le remplissage des valeurs est immédiat. La ListView contient une vingtaine de ligne dont seulement une colonne sur trois est a mettre à jour en temps réel.

    @wallace1 : j'avais creusé cette possibilité mais ca fait très compliqué surtout que mon programme déclare un thread secondaire de lui même que j'utilise pour les mise à jour.

    Je vais bosser sur l'histoire de l'invoke, je pense que c'est la solution la plus simple compte tenu de mon programme actuel.

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    il est possible de passer des paramètres via un invoke

    sinon maintenant qu'on a plus de détails, on sait que tu as peu de données, donc le mieux serait dans ton thread de remplir une variable privée avec les données du listview, à la fin de la boucle, tu fais un invoke sur une méthode qui va faire la suspension de rafraichissement et mettre les données dans le listview à partir de la variable privée
    comme ca pas de scintillement et pas de passage de paramètre, une variable privée peut etre utilisée depuis tous les threads

    si la lecture des données prend moins de 100ms et qu'elle ne peut pas bloquer, un timer aurait suffit d'ailleurs
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

Discussions similaires

  1. Problème de chargement d'une listView dans un thread
    Par Jérémy Lefevre dans le forum Composants graphiques
    Réponses: 3
    Dernier message: 12/10/2011, 17h27
  2. Executer une fonction (avec paramètres) dans un thread secondaire
    Par you38 dans le forum Threads & Processus
    Réponses: 21
    Dernier message: 06/08/2010, 08h12
  3. Fenêtres enfants dans un thread secondaire
    Par greg2 dans le forum Windows
    Réponses: 7
    Dernier message: 23/12/2009, 11h05
  4. 2 pb differents : IHM dans thread secondaire et cast en classe heritee
    Par cyrmaril dans le forum Threads & Processus
    Réponses: 18
    Dernier message: 31/07/2008, 12h12
  5. modifier données dans ListView
    Par samot dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 21/11/2007, 17h49

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