Le premier site francophone dédié au développement Pocket PC

Comment rendre un Listview multiselect ?
Auteur
Stéphane Sibué
Date 13 juin 2004
 
   


Le contrôle ListView est l'un des contrôles les plus pratiques et puissants fournit par Windows CE. Ce contrôle permet l'affichage d'informations sous la forme de listes d'icônes, ou de tableaux détaillés. C'est un contrôle qui est donc très souvet utilisé dès qu'il y a des informations à afficher sous forme de liste.

Pour faire un rapide point sur les possibilité de ce contrôle, je vous invite à lire l'article de présentation le concernant dans la rubrique eVB de CodePPC. Que ce soit en VB.NET, en C#, en C++ ou en eVB le contrôle ListView reste globalement le même et permet globalement les mêmes choses.

Le ListView .NET ne permet pas la sélection de plusieurs items à la fois !

Alors que la propriété "Multiselect" est présente avec eVB, sous VB.NET elle manque à l'appel (un comble tout de même) ce qui interdit la possibilité de sélectionner plusieurs items à la fois en cliquant au préalable sur le touche [CTRL] du clavier virtuel. Pourtant lorsqu'on regarde de plus près les propriétés liées à la sélection d'items, on se rend bien compte que le Listview gère une collection d'items sélectionnés et qu'en fait, faute de multi-sélection, on ne peut utiliser que l'élément d'indice 0 (zéro) de la collection "SelectedIndices".

Pour info, a collection qui regroupe les items sélectionnés est définie comme suit :

Public ReadOnly Property SelectedIndices() As System.Windows.Forms.ListView.SelectedIndexCollection

Il faut contourner le problème... Encore une fois !

Bon, qu'à cela ne tienne, après un petit détours par l'aide en ligne de eVC++ (toujours très utile cette aide en ligne, même quand on développe en VB.NET avec VS 2003) j'ai appris que par défaut un Listview est multiselect et qu'il faut forcer la mono sélection ! Ca veut dire que notre contrôle Listview a été intentionnellement limité ! Là, je ne comprends plus rien. Je vais d'ailleurs faire mon enquête à ce propos auprès de Microsoft et je vous tiendrai au courant.

Enlever le style qui force le Listview à être mono sélection

La solution consiste à enlever le style qui force le Listview à être mono sélection. Pour cela nous avons besoin de récupérer le handle du Listview à modifier. Nous allons utiliser la même méthode que dans l'article qui explique comment forcer un Textbox à n'accepter que des chiffres. Je vous invite à le lire pour bénéficier du détail des opérations.

Pour résumer, nous allons récupérer le handle du Listview grâce à l'API "GetFocus" et ensuite lire le style du Listview avec "GetWindowLong", le modifier pour rendre le contrôle multiselect puis le réinjecter dans le contrôle avec "SetWindowLong". C'est aussi simple que ça (les développeurs C++ font ça tout le temps).

Déclaration des API et des constantes nécessaires

Note : Pour rendre notre Listview multiselect, nous devons lui enlever le style LVS_SINGLESEL (la présence de ce style par défaut est un gros sobotage !. Bon là je me répète c'est certain, mais je suis en colère, donc c'est normal).

Private Declare Function GetFocus Lib "Coredll" () As Int32

Private Declare Function GetWindowLong Lib "coredll" Alias "GetWindowLongW" (ByVal hwnd As Int32, ByVal nIndex As Int32) As Int32

Private Declare Function SetWindowLong Lib "coredll" Alias "SetWindowLongW" (ByVal hwnd As Int32, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32

Private Const GWL_STYLE = -16
Private Const LVS_SINGLESEL As Int32 = &H4

Création d'une fonction qui automatise l'annulation du style LVS_SINGLESEL

Voici le code de notre petite fonction :

Public Function ListViewMultiSelect(ByVal wLV As ListView) As Boolean


Dim LVhWnd As Int32 Dim Retval As Int32 wLV.Focus()
    If wLV.Focus() Then
        LVhWnd = GetFocus()
        Retval = GetWindowLong(LVhWnd, GWL_STYLE)
        Retval = Retval And (Not LVS_SINGLESEL)
        SetWindowLong(LVhWnd, GWL_STYLE, Retval)
Return True Else Return False End If
End Sub

Vous pouvez utiliser cette fonction dans l'événement "Load" de la Form, ainsi vous êtes certain que l'application sera effectuée une seule fois. Cette fonction retourne "True" si elle réussit à donner le focus au Listview et à lui appliquer le style.

Conclusion

Le plus fort dans l'histoire, c'est que vous pouvez sans aucun problème récupérer tous les items sélectionnés en consultant la collection "SelectedIndices" qui reflète à merveille la situation réelle.

 

Stéphane Sibué

 

 
   

Copyright 2001-2004 - Tous droits réservés
Toutes les autres marques et produits présents dans ces pages sont la propriété exclusive de leurs sociétés respectives.