Combobox multi colonnes

Description

Bonjour, voici un contrôle personnalisé MultiColumnComboBox (MCCB) qui permet de choisir un item dans un ComboBox, parmi une liste à plusieurs colonnes.
Il en existe pas mal de versions sur le Web, mais je n'ai rien trouvé de très satisfaisant, et qui soit suffisamment paramétrable pour être souple d'emploi.

La conception de ce contrôle est la suivante :

1 - MCCB hérite du contrôle ComboBox des WinForms
2 - une première propriété ChangeBehavior permet de gérer son comportement : si False, il se comporte comme une ComboBox ; si True, le comportement change : une fenêtre Popup contenant un contrôle ListView est affichée lors d'un click de souris (gauche) dans la MCCB. La sélection dans le liste ne peut pas être multiple.
3 - si ChangeBehavior vaut True, le contenu de la ListView est paramétrable avec les propriétés suivantes :
  • ColumnIndexesToDisplay : tableau d'Int32 : indexes des colonnes à faire apparaître dans la liste
  • ColumnNamesToDisplay : tableau de String : noms des colonnes à faire apparaître dans la liste
  • DisplayIndex : Int32 : index de la colonne dont la valeur est affichée dans la MCCB lorsqu'un item est choisi (-1 signifie « pas d'index »)
  • DisplayName : String : nom de la colonne dont la valeur est affichée dans la MCCB lorsqu'un item est choisi
  • DataSource (hérité de ComboBox) : peut contenir soit une DataTable, soit un tableau de Strings à 2 dimensions ; la 1ère dimension représente les lignes de la liste, la 2ème dimension représente les colonnes


La colonne spécifiée dans DisplayName ou DisplayIndex peut faire partie - ou non - des colonnes affichées dans la liste. En gros, cela peut être une colonne « cachée ».

De plus, le message CBN_DROPDOWN est intercepté pour empêcher la liste native du ComboBox de s'afficher.

4 - Contenu de la ListView : lorsque DataSource est une DataTable :
  • Si ColumnIndexesToDisplay ET ColumnNamesToDisplay sont vides ou Nothing, toutes les colonnes sont affichées
  • Si ColumnIndexesToDisplay ET ColumnNamesToDisplay sont renseignées, c'est ColumnIndexesToDisplay qui est prioritaire
  • Les titres des colonnes sont les noms des DataColumns
  • Il n'y a pas de filtre sur les DataRows


5 - Contenu de la ListView : lorsque DataSource est un String()() :
  • Toutes les colonnes sont toujours affichées
  • ColumnIndexesToDisplay est ignorée, et ColumnNamesToDisplay sert de titres aux colonnes
  • DisplayName est ignorée
  • Il n'y a pas de filtres sur les lignes


6 - les propriétés suivantes sont accessibles depuis le Designer de Visual Studio : ChangeBehavior, ColumnIndexesToDisplay, ColumnNamesToDisplay, DisplayIndex, DisplayName

7 - lorsqu'un item de la liste est sélectionné, la valeur contenue dans la colonne désignée par DisplayIndex ou DisplayName est affichée via la propriété Text de la ComboBox.
De plus, un évènement de type AfterItemSelect est généré. Un gestionnaire peut être ajouté, une structure de type MultiColumnComboBoxSelection est disponible. Elle contient les champs :
  • Row : DataRow de l'item sélectionné si DataSource est de type DataTable, sinon Nothing
  • Values : tableau de String de l'item sélectionné si Datasource est de type String()()
  • Index : int32 contenant l'index de l'item sélectionné


8 - pour récupérer les données de l'item sélectionné sans passer par l'évènement AfterItemSelect, les propriétés SelectedMultiIndex et SelectedMultiItem sont utilisables de la manière suivante :
Dim si As Integer = instance_mccb.SelectedMultiIndex
Dim val_col2 As String = instance_mccb.SelectedMultiItem(2)

Seules les valeurs des colonnes affichées dans la ListView sont accessibles via la propriété SelectedMultiItem.

9 - la fonctionnalité de tri ne peut pas interférer dans le fonctionnement du contrôle MCCB, car la ComboBox interdit de positionner Sorted à True si DataSource est renseignée

10 - Les méthodes suivantes sont disponibles :
  • KeyColumnContains : permet de déterminer si la clé primaire à 1 colonne de la DataTable contient une valeur donnée
  • KeyColumnsContain : permet de déterminer si la clé primaire à plusieurs colonnes de la DataTable contient une valeur donnée
  • ColumnContains : permet de déterminer si une colonne quelconque contient une valeur donnée
  • ColumnIndexOf : permet de déterminer l'index du premier item de la liste qui contient une valeur donnée dans une colonne donnée ; retourne -1 si valeur pas trouvée

Source / Exemple :


il y a en pièce jointe les fichiers pour le contrôle lui-même :
- MultiColumnComboBox.vb
- MultiColumnComboPopup.resx
- MultiColumnComboPopup.vb

et pour le tester :

- Form1.vb
- Form1.resx
- Form1.Designer.vb

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.