Listview "bloquée

Résolu
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013 - 27 sept. 2011 à 18:44
 Utilisateur anonyme - 29 sept. 2011 à 20:53
Bon, je fais encore appel au public car je fais face à un problème incompréhensible.

J'ai créé une Listview, tout simplement car je souhaitais une Listbox dont je peux changer la couleur des lignes.
J'ai donc ajusté toutes les propriétés de manière à ce que la Listview ressemble le plus possible à une Listbox (View sur "List", MultiSelect sur False, etc.).

J'ajoute des items dedans, tout se passe bien, je peux les sélectionner.
Mais une des lignes de ma Listview lance une boucle, qui ne doit pas s'arrêter tant que je n'ai pas à nouveau sélectionné une autre ligne de la Listview. J'ai donc ajouté un "My.Application.Doevents", qui me permet de faire tout un tas d'autres opérations telles que cliquer sur des boutons, des Combobox etc.

Pourtant, le seul contrôle qui ne réagit plus est... la listview. J'ai tout essayé, impossible de déclencher à nouveau son événement "click", et je suis sur que le problème vient de la boucle, car en retirant celle-ci, la listview ne se bloque jamais.

Si vous avez une idée, elle sera la bienvenue...

Voici le code de façon très très simplifiée :

Private Sub ListView1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.Click

Boucle()

End Sub

Sub Boucle ()
Do while MaBoucle = True
My.Application.DoEvents()
Loop
End Sub

27 réponses

NHenry Messages postés 15144 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 24 juillet 2024 159
27 sept. 2011 à 20:35
Bonjour,

Je dirais, que tant que tu n'es pas sorti du gestionnaire de l'événement Click, il ne peut en générer un autre, d'où ma suggestion du Timer ou du Thread.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS et aussi ce lien[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
3
NHenry Messages postés 15144 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 24 juillet 2024 159
27 sept. 2011 à 21:45
Bonjour,

Je pense qu'un Timer ou un thread serait plus adapté au besoin et moins gourmand en ressource.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS et aussi ce lien[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
3
Utilisateur anonyme
27 sept. 2011 à 22:58
Bonsoir,

Un petit exemple simple sur le threading pourra t'aider.
Ce n'est peut-être pas la bonne manière de faire mais c'est la mienne.

Ici, on lance un thread dans une boucle infinie et on le stoppe (abort) lors du clic suivant et ainsi de suite. Une information provenant du thread doit être affichée sur un label dans le thread principal (Form1).
Il faut donc aussi gérer les opérations inter-threads. D'où l'utilité d'un délégué.

A tester avec un Label et une ListView

Tu remarquera qu'on utilise l'événement ItemSelectionChanged plutôt que Click de manière à récupérer le paramètre d'événement (e) qui contient des informations sur l'item cliqué.
Ces dernières peuvent être alors passés en paramètre lors du lancement du thread (Start) et être utilisées dans le thread.

Et par pitié, pas de DoEvents

Option Strict On
Public Class Form1
    'thread à lancer
    Dim t As Threading.Thread
    'délégué avec son paramètre string
    Delegate Sub DelegueClick(ByVal Texte As String)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'ajout d'éléments
        ListView1.Items.Add("titi")
        ListView1.Items.Add("toto")
        ListView1.Items.Add("tata")
    End Sub

    Private Sub ListView1_ItemSelectionChanged(ByVal sender As Object, ByVal e As ListViewItemSelectionChangedEventArgs) Handles ListView1.ItemSelectionChanged
        Label1.Text = "0"
        'si le thread existe et qu'il est actif, on le stoppe
        If t IsNot Nothing Then
            If t.IsAlive Then t.Abort()
        End If
        t = Nothing
        'on lance un nouveau thread (en lui demandant d'exécuter la procédure Job)
        t = New Threading.Thread(AddressOf Job)
        'remarque : la méthiode Start autorise le passage d'un paramètre objet utilisable ensuite dans le thread
        t.Start()
    End Sub

    Private Sub Job()
        Dim x As Integer
        'simulation d'un calcul long et pénible ...
        Do
            Threading.Thread.Sleep(1000)
            'on peut vouloir afficher des informations comme des resultats de calculs pendant l'exécution du thread
            If x 2 Or x 5 Or x = 8 Then
                'exemple d'invocation d'un délégué (opérations inter-threads)
                'ce délégué doit exécuter la procédure ItemClick
                'on peut passer un ou plusieurs paramètres au délégué ici je passe x (en string)
                If Me.InvokeRequired Then
                    Me.Invoke(New DelegueClick(AddressOf ItemClick), x.ToString)
                End If
            End If
            x += 1
        Loop
    End Sub

    'procédure appelée par le délégué avec le paramètre string que l'on peut afficher dans le label
    Private Sub ItemClick(ByVal Texte As String)
        Label1.Text = Texte
    End Sub
End Class

Bonne nuit.
3
NHenry Messages postés 15144 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 24 juillet 2024 159
27 sept. 2011 à 19:07
Bonjour,

Préfère utiliser un timer ou un Thread plutot.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS et aussi ce lien[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 209
27 sept. 2011 à 19:09
Bonjour,
comment veux-tu qu'on te réponde, avec uniquement ce que tu montres ?

Il nous faut savoir :
- où et comment est déclarée maboucle
- où et comment tu passes à False sa valeur

____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 19:18
Je suis justement en train de me documenter sur les thread, mais j'avoue que ça à l'air bien compliqué.

ucfoutu :

Je ne pense pas que ce soit très important...
Comme je l'ai dit, c'est lorsque je sélectionne une ligne particulière que la boucle s'active (et donc que maboucle prend la valeur "true") et elle est déclarée comme ça :
Public MaBoucle as boolean


le problème ne vient sûrement pas de cette variable
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 209
27 sept. 2011 à 19:23
Comme je l'ai dit, c'est lorsque je sélectionne une ligne particulière que la boucle s'active (et donc que maboucle prend la valeur "true")

Public MaBoucle as boolean



le problème ne vient sûrement pas de cette variable


Tiens donc !
Elle passe )à True ===>> OK
Mais tant que pas passée à False ===>> ta boucle Do continue (et à l'infini tant que macoucle = True) !


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 19:28
Exact, d'où le DoEvents
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
27 sept. 2011 à 19:41
Salut

"qui ne doit pas s'arrêter tant que je n'ai pas à nouveau sélectionné une autre ligne"
Où se trouve l'arrêt ?
A mon avis, c'est là qu'est le problème.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 19:46
Je n'ai pas besoin d'arrêt, puisqu'il existe le DoEvents. L'arrêt c'est la sélection d'une autre ligne qui donne la valeur False à MaBoucle.
Je vais vous envoyer le code réécrit et plus élaboré :

Private Sub ListView1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.Click

If ListView1.SelectedItems(0).Text = "JeLanceLaBoucle" then
MaBoucle = True
Boucle()
Else
MaBoucle = False
Exit Sub
end if

End Sub

'Dans un module :

Public MaBoucle as Boolean

Sub Boucle ()

Do while MaBoucle = True

'Instructions diverses

My.Application.DoEvents()
Loop

End Sub
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 209
27 sept. 2011 à 20:13
Si (et tu l'as dit) ta variable maboucle est publique et de type boolean, il est simple de faire ceci, quand-même :

Private Sub ListView1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.Click
  maboucle = Not maboucle
   Do While maboucle = True
     ' .... ce que tu veux 
    My.Application.DoEvents()
   Loop
  End Sub


Non ?
____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 20:19
Ca ne m'a pas l'air plus simple, mais dans tous les cas, l'événement Click ne répond plus.

J'ai essayé de mettre un msgbox en première ligne

Private Sub ListView1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.Click
msgbox "Test"

End Sub


Mais je n'ai pas de réaction. Et puis tous les autres contrôles répondent, pourquoi il n'y aurait que la ListView qui ne répond plus ?
Avant de passer à la ListView, j'avais une ListBox normale et je n'avais absolument aucun problème.


Au fait, merci à tous pour vos réponses
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 20:21
En fait c'est un peu comme si ma ListView était en Enabled = false

Tant que je sélectionne des lignes qui n'envoient pas la boucle, aucun problème, et dès que la boucle est lancée, impossible de changer de ligne, elles ne sont plus surlignées (et cela se comprend facilement : l'événement click ne se lance pas.)
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 209
27 sept. 2011 à 20:48
Ne me dites surtout pas (j'espère bien que non) que VB.Net est dans ce domaine plus infirme que son aieul VB6 !

Il se trouve que ceci, mis dans l'évènement click de la listview, fonctionne fort bien et fort simplement en VB6, pour autant que l'on clique sur une colonne autre que la toute première

maboucle = Not maboucle
 Do While maboucle = True
  Label1.Caption = "ccc"
  DoEvents
 Loop
 Label1.Caption = ""


et si je mets (presque) la même chose dans l'évènement itemclik, (presque par ce que là, je n'inverse pas la valeur de ma boucle) ===>>
Do While maboucle = True
  Label1.Caption = "ccc"
  DoEvents
 Loop
 Label1.Caption = ""


La conjugaison des deux fait que j'ai exactement ce que tu souhaites, que l'on clique dans la première colonne ou dans une autre !



A toi d'adapter avec ton super outil (moi, je n'ai que VB6 )
Je pense en particulier à la propriété Caption d'un Label (je ne sais pas ce qu'elle est sous VB.Net).
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 20:56
Je travaillais avec vba ppt97 avant (qui a un peu l'air de ressembler à vb6 !), et malgré son ancienneté, il était capable de gérer facilement les boucles avec DoEvents.

vb.net en est aussi capable, puisque mon code fonctionnait très bien avec une ListBox, et que les autres contrôles sont accessibles, mais là je sais pas pourquoi, ça bloque

NHenry : oui j'ai remarqué qu'il ne procédait même pas aux instructions qui suivent "Boucle()"

ListView.Click......

Boucle()

msgbox "test"



Mais je trouve ça quand même incroyable que ça marche avec une ListBox... Je vais continuer à chercher un peu
0
cs_ShayW Messages postés 3253 Date d'inscription jeudi 26 novembre 2009 Statut Membre Dernière intervention 3 décembre 2019 57
27 sept. 2011 à 21:01
Salut
Mais une des lignes de ma Listview lance une boucle, qui ne doit pas s'arrêter tant que je n'ai pas à nouveau sélectionné


Pourquoi as tu besoin de faire une boucle ?
0
NHenry Messages postés 15144 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 24 juillet 2024 159
27 sept. 2011 à 21:01
Bonjour,

Je me pose la question suivante :
Quelle est la finalité de ton code ?
Car peut être qu'une autre technique serait appréciable.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS et aussi ce lien[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 21:08
Il s'agit d'un petit logiciel de conversation.

La Listview affiche les contacts, en rouge ou en vert selon qu'ils sont connectés ou non.
Si ils le sont, ma fameuse boucle se lance, et vérifie si la personne a envoyé un message ou non (imbriquer la boucle dans le listview me semble tendancieux... C'est pourquoi je l'ai créée dans un module à part, et encore une fois ça marchait très bien lorsque j'avais une simple ListBox, le seul problème c'était les couleurs des lignes, et les icônes, si jamais je veux en ajouter plus tard)
Si je sélectionne un contact non connecté, la boucle conversation s'arrête (car plus besoin de vérifier que quelqu'un me parle ou non)

Mais lorsque je sélectionne un contact en ligne (ne me demandez pas les procédés réseau, tout est bien prévu), ma listview se bloque, alors même que je peux faire tout un tas d'autres opérations (changer d'avatar, ajouter des textes prédéfinis, et bien sûr envoyer un message à la personne).

Je trouve ce problème incompréhensible
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 21:48
D'accord, il va vraiment falloir que je planche dessus alors... Ça à l'air super (parce que j'aimerai développer des application utilisant des instructions parallèles) mais dur à apprendre...
0
djedjeska Messages postés 90 Date d'inscription mercredi 21 novembre 2007 Statut Membre Dernière intervention 25 mai 2013
27 sept. 2011 à 22:41
Bon, j'ai utilisé un backgroundworker, dans lequel j'ai inséré ma procédure "boucle".
Non seulement c'est super simple à utiliser, mais en plus ça a réglé mon problème de blocage...

Merci à tous, et notamment à NHenry pour l'idée du thread
0
Rejoignez-nous