none
La multi-sélection dans un listview par le code ne marche pas dans certains cas ? RRS feed

  • Question

  • Bonjour,

    J'ai un listview dans lequel l'utilisateur peut cliquer. Quand l'utilisateur sélectionne sur une ligne particulière, le code impose la sélection de plusieures lignes contigues. Pas de problèmes si l'utilisateur utilise les flêches du clavier, par contre ça ne marche pas en utilisant la souris.

    Voici un exemple simple:

    J'ai un listview "lvwMultiSelect" (avec la propriété .MultiSelect = True) avec 4 éléments (indices 0, 1, 2 et 3).

    Dans l'évènement lvwMultiSelect_ItemSelectionChanged, je précise que si la ligne d'indice 2 est sélectionnée, la sélection réelle sera 0+1+3:

     Private Sub lvwMultiSelect_ItemSelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.ListViewItemSelectionChangedEventArgs) Handles lvwMultiSelect.ItemSelectionChanged
    
      Debug.Print("lvwMultiSelect_ItemSelectionChanged " & e.ItemIndex.ToString & " " & e.Item.ToString & " nb sel=" & lvwMultiSelect.SelectedIndices.Count.ToString)
    
      If (e.ItemIndex = 2) And e.IsSelected Then
    
       lvwMultiSelect.SelectedIndices.Clear()
    
       lvwMultiSelect.SelectedIndices.Add(0)
    
       lvwMultiSelect.SelectedIndices.Add(1)
    
       lvwMultiSelect.SelectedIndices.Add(3)
    
       lvwMultiSelect.Items(3).Focused = True
    
    
      End If
    
     End Sub
    
    
    
    

    Cet évènement se déclenche à toute modification de la sélection dans le listview, avec flêches du clavier ou souris.

    Avec les flêches du clavier, ça marche parfaitement, tandis qu'avec la souris, la multisélection est réalisée, puis les éléments sont dé-sélectionnés...

     Pourtant, c'est le même évènement qui est déclenché, et aucun autre évènement n'est renseigné. Je pense à un évènement intrinsèque au contrôle listview (invisible au développeur) qui réimposerai la sélection cliquée sur un clic de souris, après que l'évènement lvwMultiSelect_ItemSelectionChanged soit réalisé...

    Quelqu'un aurait-il la solution pour faire fonctionner cet exemple tout simple ?

    Merci d'avance


    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    • Déplacé Alex Petrescu mardi 29 juin 2010 10:19 (Origine :Windows Forms)
    lundi 28 juin 2010 13:23

Réponses

  • Bonjour,

     

    Vous pouvez utiliser votre code dans l’évènement SelectIndexChanged :

     

        Private Sub lvwMultiSelect_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvwMultiSelect.SelectedIndexChanged

     

            If Me.lvwMultiSelect.FocusedItem.Index = 2 Then

     

                lvwMultiSelect.SelectedIndices.Add(0)

     

                lvwMultiSelect.SelectedIndices.Add(1)

     

                lvwMultiSelect.SelectedIndices.Add(3)

            Else

                lvwMultiSelect.SelectedItems.Clear()

     

            End If

        End Sub

     

     

    Mais à cause de la nature de ces opérations, je ne sais pas s’il y a un moyen d’obtenir exactement ce que vous voulez. Les méthodes SelectedIndices.Add et Clear() appellent à leur tour l’évènement SelectedIndexChanged, ce qui crée une boucle dans l’appel de la méthode lvwMultiSelect_SelectedIndexChanged.

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Workflow Foundation, WPF

     

     

    Café des usages

     

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    • Marqué comme réponse Alex Petrescu lundi 5 juillet 2010 08:19
    mardi 29 juin 2010 11:01

Toutes les réponses

  • Bonjour,

     

    Vous pouvez utiliser votre code dans l’évènement SelectIndexChanged :

     

        Private Sub lvwMultiSelect_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvwMultiSelect.SelectedIndexChanged

     

            If Me.lvwMultiSelect.FocusedItem.Index = 2 Then

     

                lvwMultiSelect.SelectedIndices.Add(0)

     

                lvwMultiSelect.SelectedIndices.Add(1)

     

                lvwMultiSelect.SelectedIndices.Add(3)

            Else

                lvwMultiSelect.SelectedItems.Clear()

     

            End If

        End Sub

     

     

    Mais à cause de la nature de ces opérations, je ne sais pas s’il y a un moyen d’obtenir exactement ce que vous voulez. Les méthodes SelectedIndices.Add et Clear() appellent à leur tour l’évènement SelectedIndexChanged, ce qui crée une boucle dans l’appel de la méthode lvwMultiSelect_SelectedIndexChanged.

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Workflow Foundation, WPF

     

     

    Café des usages

     

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    • Marqué comme réponse Alex Petrescu lundi 5 juillet 2010 08:19
    mardi 29 juin 2010 11:01
  • Bonjour Alex,

    J'ai renseigné l'évènement SelectedIndexChanged comme vous le précisez, en prenant soin de n'avoir QUE cet évènement de renseigné:

      Private Sub lvwMultiSelect_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvwMultiSelect.SelectedIndexChanged
    
     
    
        If Me.lvwMultiSelect.FocusedItem.Index = 2 Then
    
     
    
          lvwMultiSelect.SelectedIndices.Add(0)
    
     
    
          lvwMultiSelect.SelectedIndices.Add(1)
    
     
    
          lvwMultiSelect.SelectedIndices.Add(3)
    
        Else
    
          lvwMultiSelect.SelectedItems.Clear()
    
     
    
        End If
    
      End Sub
    
    

     Je vous confirme un comportement "étrange" des sélections effectuées par le code:

    • en cliquant sur l'item 0 : rien. Normal, on a déclenché le Clear
    • en cliquant sur l'item 1 : rien. Normal, on a déclenché le Clear
    • en cliquant sur l'item 2 : sélection auto des 4 items. Normal c'est ce qui est codé

    C'est là que le comportement n'est plus logique:

    • en recliquant sur l'item 2: toujours sélection des 4 items. Normal.
    • en cliquant sur l'item 3: l'item 0 est désectionné instantanément, on voit ensuite l'item 1 se déselectionner... l'item 2 reste sélectionné, ainsi que l'item 3. Normalement, le Clear aurait du tout désélectionner !???
    • en cliquant sur l'item 1: l'item 3 est déselectionné, mais l'item 2 reste sélectionné. les items 0 et 1 sont désélectionnés... Là aussi, le Clear aurait du tout désélectionner !???
    • en cliquant sur l'item 2: sélection des 4. Normal.
    • en cliquant sur l'item 0: l'item 0 est désélectionné, tandis que les 3 autres restent sélectionnés !???
    • etc, etc...

    Comme vous le constatez, ce comportement inattendu m'empêche d'effectuer une multisélection par le code.

    Si quelqu'un trouve la solution, je suis preneur !

    Merci à tous,

    (PS: Pour mes réponses, veuillez noter que je serai absent jusqu'au 19 juillet.)


    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    vendredi 2 juillet 2010 07:25
  • Bonjour,

     

    Ajouter un ‘break-point’ dans la méthode appelée par l’élément et vous aurez une image plus claire sur ce que se passe. Chaque méthode SelectedIndices.Add lance l’évènement et appelle à son tour SelectedIndexChanged, vous allez voir ça en mode debug. Aussi, la méthode Clear modifie le SelectedIndex et appelle la même méthode SelectedIndexChanged. Cette méthode lvwMultiSelect_SelectedIndexChanged est appelle plusieurs fois à partir des évènements qui sont lancées à l’intérieur d’elle-même, ce que résulte dans le comportement que vous venez de décrire et que j’ai aussi remarqué. Je ne vois aucune solution pour faire un Clear() sans appeler à nouveau la méthode SelectedIndexChanged.

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Silverlight, Workflow Foundation, WPF

    Café des usages

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    vendredi 2 juillet 2010 10:28