locked
Quel composant VbNet remplace l'Image ComboBox de Vb6 ??? RRS feed

  • Question

  • Bonjour,

    Je ne trouve pas le composant (intégré à la plateforme dotnet) qui remplace le composant Vb6 MSComctlLib.ImageCombo

    Quelqu'un peut-il m'indiquer quel composant utiliser pour le remplacer dans le cadre d'une migration de projet Vb6 vers VbNet ?

    En espérant avoir mal cherché, et que donc vous pourrez m'aider, merci d'avance...
    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    lundi 15 février 2010 11:05

Réponses

  • Bonjour,

    je ne connais pas le composant ImageCombo mais vous avez la possibilité d'intégrer des images au sein de la ComboBox .net en dessinant vous même les items de la liste.
    Pour cela vous devez :
    -  affecter la propriété DrawMode = DrawMode.OwnerDrawVariable
    -  surcharger l'event DrawItem de la combobox.

    Voici un exemple ci dessous un utilisant une ImageList contenant les images :

    Public Sub New()
    
    ....
    
         ' Add any initialization after the InitializeComponent() call.
         For i = 1 To Me.ImageList1.Images.Count
             Me.ComboBox1.Items.Add(String.Format("item {0}", i))
    
         Next
    
         Me.ComboBox1.DrawMode = DrawMode.OwnerDrawVariable
    
     End Sub
    
    
    
    
    Private Sub ComboBox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
    
        If (e.Index <> -1) Then
    
            e.Graphics.DrawImage(ImageList1.Images(e.Index), e.Bounds.Left, e.Bounds.Top)
    
            e.Graphics.DrawString(Me.ComboBox1.Items(e.Index).ToString(), e.Font, System.Drawing.Brushes.Black, e.Bounds.Left + ImageList1.Images(e.Index).Width, e.Bounds.Top)
    
        End If
    
    End Sub




    • Marqué comme réponse Alex Petrescu mercredi 17 février 2010 12:56
    lundi 15 février 2010 13:40
  • Bonjour,

    voici un exemple qui pourra te servir de base de travail.

    Tout d'abord on définit une classe Item qui portera les informations clé, valeur et référence de l'image.
    Public Class Item
    
        Public Sub New(ByVal key As Integer, ByVal display As String, ByRef image As System.Drawing.Image)
            Me.Key = key
            Me.Display = display
            Me.Image = image
        End Sub
    
    
        Private _key As Integer
        Public Property Key() As Integer
            Get
                Return Me._key
            End Get
            Set(ByVal value As Integer)
                Me._key = value
            End Set
        End Property
    
        Private _display As String
        Public Property Display() As String
            Get
                Return Me._display
            End Get
            Set(ByVal value As String)
                Me._display = value
            End Set
        End Property
    
        Private _image As System.Drawing.Image
        Public Property Image() As Image
            Get
                Return Me._image
            End Get
            Set(ByVal value As System.Drawing.Image)
                Me._image = value
            End Set
        End Property
    
    End Class

    Comme précédemment on utilise une imagelist qui contient les images.
    On initialise une liste générique d'item puis on l'associe par databinding à la combo

    Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            Dim list As New List(Of Item)()
            list.Add(New Item(1, "Libelle1", ImageList1.Images(0)))
            list.Add(New Item(2, "Libelle2", ImageList1.Images(1)))
            list.Add(New Item(3, "Libelle3", ImageList1.Images(2)))
            list.Add(New Item(4, "Libelle4", ImageList1.Images(3)))
    
            Me.ComboBox1.ValueMember = "Key"
            Me.ComboBox1.DisplayMember = "Display"
            Me.ComboBox1.DataSource = list
    
            Me.ComboBox1.DrawMode = DrawMode.OwnerDrawVariable
            Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
            Me.ComboBox1.Focus()
    
    
    End Sub

    Ensuite la surchage de l'event DrawItem. Ici on considére que notre combo est toujours liée à une liste de ce type.
    Pour éviter que tous les éléments soit surlignés, il faut tester la sélection via DrawItemState.Selected

    Private Sub ComboBox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
            If (e.Index <> -1) Then
    
                'gestion d'une combo associée à objet item
                If TypeOf (Me.ComboBox1.DataSource) Is List(Of Item) Then
    
                    'item courant
                    Dim item As Item = CType(Me.ComboBox1.Items(e.Index), Item)
    
                    'gestion couleur de fond si item sélectionné : par ex fond gris
                    If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                        e.Graphics.FillRectangle(System.Drawing.Brushes.Gray, e.Bounds)
                    Else
                        e.DrawBackground()
                    End If
    
                    'dessin image
                    e.Graphics.DrawImage(item.Image, e.Bounds.Left, e.Bounds.Top)
    
                    'dessin libellé
                    e.Graphics.DrawString(item.Display, e.Font, System.Drawing.Brushes.Black, e.Bounds.Left + item.Image.Width, e.Bounds.Top)
    
                    'focus
                    e.DrawFocusRectangle()
                End If
    
            End If
        End Sub

    Ensuite pour récupérer l'item sélectionné sur un click de bouton par ex :

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show(CType(Me.ComboBox1.SelectedItem, Item).Key)
    End Sub

    Voilà en espérant que cela te sera utile ( une petite précision VB.Net n'est pas le langage avec lequel je suis le plus familier, j'ai donc utilisé un peu de convertisseur de code en espérant que la syntaxe reste qd même adaptée...)

    Cordialement.










    • Marqué comme réponse Alex Petrescu mercredi 17 février 2010 12:57
    mercredi 17 février 2010 09:55
  • Bonjour,

    si tu passes Key As String et modifies le constructeur on peut alors ajouter les items  avec:

    Dim list As New List(Of Item)()
    list.Add(New Item("key1", "Libelle1", ImageList1.Images(0)))
    et on récupère bien "key1"

    Cordialement

    • Marqué comme réponse Golard vendredi 19 février 2010 08:32
    mercredi 17 février 2010 12:55

Toutes les réponses

  • Bonjour,

    je ne connais pas le composant ImageCombo mais vous avez la possibilité d'intégrer des images au sein de la ComboBox .net en dessinant vous même les items de la liste.
    Pour cela vous devez :
    -  affecter la propriété DrawMode = DrawMode.OwnerDrawVariable
    -  surcharger l'event DrawItem de la combobox.

    Voici un exemple ci dessous un utilisant une ImageList contenant les images :

    Public Sub New()
    
    ....
    
         ' Add any initialization after the InitializeComponent() call.
         For i = 1 To Me.ImageList1.Images.Count
             Me.ComboBox1.Items.Add(String.Format("item {0}", i))
    
         Next
    
         Me.ComboBox1.DrawMode = DrawMode.OwnerDrawVariable
    
     End Sub
    
    
    
    
    Private Sub ComboBox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
    
        If (e.Index <> -1) Then
    
            e.Graphics.DrawImage(ImageList1.Images(e.Index), e.Bounds.Left, e.Bounds.Top)
    
            e.Graphics.DrawString(Me.ComboBox1.Items(e.Index).ToString(), e.Font, System.Drawing.Brushes.Black, e.Bounds.Left + ImageList1.Images(e.Index).Width, e.Bounds.Top)
    
        End If
    
    End Sub




    • Marqué comme réponse Alex Petrescu mercredi 17 février 2010 12:56
    lundi 15 février 2010 13:40
  • Impressionnant ! Merci Nikho !

    L'image s'affiche bien dans la liste.
    J'ai renseigné la propriété DropDownStyle afin que l'image s'affiche également dans la combo une fois refermée:

    DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList

    Par contre je n'arrive pas à donner le focus à la combo !??? Idem quand je parcours la liste avec le curseur de la souris, l'élément sous le curseur n'est pas surligné... Comment faire ?

    Par ailleurs, j'ai un autre soucis plus embettant.
    Le composant Vb6 MSComctlLib.ImageCombo disposait pour chacun de ses éléments d'une clef.
    A l'ajoût d'un élément la syntaxe était:

    ImageCombo.Add(item, key, before, after)

    Et on retrouvait simplement la clef de l'élément sélectionné avec:

    ImageCombo.SelectedItem.Key

    Malheureusement, je ne trouve aucune propriété "Name" (remplaçant du "Key" Vb6)  aux Items de ComboBox de VbNet... La seule propriété que je trouve est l'index (je ne me vois pas gérer des centaines de tables de correspondance index/clef, car mon code actuel fonctionne par clef)

    As-tu une solution pour ce petit problème de focus et surtout pour la sélection par clef ?

    Pour info, le composant ImageCombo de Vb6 est présent dans MSComCtl.ocx. C'est lui qui contenait les contrôle "évolués"
     Listview, Treeview, ...:

       MSComCtl.ocx   Microsoft Windows Common Controls 6.0
                      Version: 6.00.8177
                      Size: 1,062,704 bytes
                      Source Directory: \os\system
                      Controls: ImageCombo
                                ImageList
                                ListView
                                ProgressBar
                                Slider
                                StatusBar
                                TabStrip
                                ToolBar
                                TreeView

     


    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    mardi 16 février 2010 09:23
  • Bonjour,

    effectivement il n'y a pas d'indication graphique si un élément est sélectionné. L'event par défaut ayant été surchargé la surbrillance par défaut n'est plus présente et vous devez vous même la coder. Vous pouvez par exemple écrire le code suivant avant le dessin des images et text pour obtenir un surlignage gris :

    e.Graphics.FillRectangle(System.Drawing.Brushes.Gray, e.Bounds)

    Pour gérer votre clé, vous pourriez créer un objet qui portera ces informations : par exemple un objet Item avec les propriétés
    - clé
    - libellé
    - éventuellement Image

    Vous associez alors votre combo à une List(Of Item) et vous pourrez alors récupérer un peu comme avant la clé de l'item sélectionné avec : CType(Me.ComboBox1.SelectedItem, Item).Key


    Cordialement
    • Marqué comme réponse Alex Petrescu mercredi 17 février 2010 12:56
    • Non marqué comme réponse Golard vendredi 19 février 2010 08:32
    mardi 16 février 2010 10:27
  • Merci nikho pour tes conseils,

    Pour le e.Graphics.FillRectangle, effectivement ça colore le background du contrôle, mais aussi celui de toute la liste (au lieu de se limiter à l'élément sélectionné puis celui survolé avec le curseur)... ??? Comme tu vois, je ne suis pas très familier avec les manipulations "manuelles" de l'environnement graphique (le principe sous vb6 était justement d'exploiter au maximum les contrôles mis à notre disposition).

    Pour l'association d'une List(Of Item) à la combo, ça m'a l'air très intéressant ! Il faudra que j'essaye de coder ça... Si tu as un exemple je suis bien sur preneur...

    A +,

    Cordialement
    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    mercredi 17 février 2010 09:26
  • Bonjour,

    voici un exemple qui pourra te servir de base de travail.

    Tout d'abord on définit une classe Item qui portera les informations clé, valeur et référence de l'image.
    Public Class Item
    
        Public Sub New(ByVal key As Integer, ByVal display As String, ByRef image As System.Drawing.Image)
            Me.Key = key
            Me.Display = display
            Me.Image = image
        End Sub
    
    
        Private _key As Integer
        Public Property Key() As Integer
            Get
                Return Me._key
            End Get
            Set(ByVal value As Integer)
                Me._key = value
            End Set
        End Property
    
        Private _display As String
        Public Property Display() As String
            Get
                Return Me._display
            End Get
            Set(ByVal value As String)
                Me._display = value
            End Set
        End Property
    
        Private _image As System.Drawing.Image
        Public Property Image() As Image
            Get
                Return Me._image
            End Get
            Set(ByVal value As System.Drawing.Image)
                Me._image = value
            End Set
        End Property
    
    End Class

    Comme précédemment on utilise une imagelist qui contient les images.
    On initialise une liste générique d'item puis on l'associe par databinding à la combo

    Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            Dim list As New List(Of Item)()
            list.Add(New Item(1, "Libelle1", ImageList1.Images(0)))
            list.Add(New Item(2, "Libelle2", ImageList1.Images(1)))
            list.Add(New Item(3, "Libelle3", ImageList1.Images(2)))
            list.Add(New Item(4, "Libelle4", ImageList1.Images(3)))
    
            Me.ComboBox1.ValueMember = "Key"
            Me.ComboBox1.DisplayMember = "Display"
            Me.ComboBox1.DataSource = list
    
            Me.ComboBox1.DrawMode = DrawMode.OwnerDrawVariable
            Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
            Me.ComboBox1.Focus()
    
    
    End Sub

    Ensuite la surchage de l'event DrawItem. Ici on considére que notre combo est toujours liée à une liste de ce type.
    Pour éviter que tous les éléments soit surlignés, il faut tester la sélection via DrawItemState.Selected

    Private Sub ComboBox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
            If (e.Index <> -1) Then
    
                'gestion d'une combo associée à objet item
                If TypeOf (Me.ComboBox1.DataSource) Is List(Of Item) Then
    
                    'item courant
                    Dim item As Item = CType(Me.ComboBox1.Items(e.Index), Item)
    
                    'gestion couleur de fond si item sélectionné : par ex fond gris
                    If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                        e.Graphics.FillRectangle(System.Drawing.Brushes.Gray, e.Bounds)
                    Else
                        e.DrawBackground()
                    End If
    
                    'dessin image
                    e.Graphics.DrawImage(item.Image, e.Bounds.Left, e.Bounds.Top)
    
                    'dessin libellé
                    e.Graphics.DrawString(item.Display, e.Font, System.Drawing.Brushes.Black, e.Bounds.Left + item.Image.Width, e.Bounds.Top)
    
                    'focus
                    e.DrawFocusRectangle()
                End If
    
            End If
        End Sub

    Ensuite pour récupérer l'item sélectionné sur un click de bouton par ex :

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show(CType(Me.ComboBox1.SelectedItem, Item).Key)
    End Sub

    Voilà en espérant que cela te sera utile ( une petite précision VB.Net n'est pas le langage avec lequel je suis le plus familier, j'ai donc utilisé un peu de convertisseur de code en espérant que la syntaxe reste qd même adaptée...)

    Cordialement.










    • Marqué comme réponse Alex Petrescu mercredi 17 février 2010 12:57
    mercredi 17 février 2010 09:55
  • Génial, ton convertisseur fonctionne très bien !

    J'ai fait une petite modif pour retrouver les couleurs système pour l'Item sélectionné dans la combo (nommée cboboxWindows2):

    Private Sub cboboxWindows2_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles cboboxWindows2.DrawItem
    
    If (e.Index <> -1) Then
    
    'gestion d'une combo associe objet item
    
    If TypeOf (cboboxWindows2.DataSource) Is List(Of Item) Then
    
    'item courant
    
    Dim item As Item = CType(cboboxWindows2.Items(e.Index), Item)
    
    'gestion couleur de fond si item slectionn : par ex fond gris
    
    If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
    
    e.Graphics.FillRectangle(New SolidBrush(System.Drawing.SystemColors.Highlight), e.Bounds)
    
    'dessin libell
    
    e.Graphics.DrawString(item.Display, e.Font, New SolidBrush(System.Drawing.SystemColors.HighlightText), e.Bounds.Left + item.Image.Width, e.Bounds.Top)
    
    Else
    
    e.DrawBackground()
    
    'dessin libell
    
    e.Graphics.DrawString(item.Display, e.Font, New SolidBrush(System.Drawing.SystemColors.WindowText), e.Bounds.Left + item.Image.Width, e.Bounds.Top)
    
    End If
    
    'dessin image
    
    e.Graphics.DrawImage(item.Image, e.Bounds.Left, e.Bounds.Top)
    
    'focus
    
    e.DrawFocusRectangle()
    
    End If
    
    End If
    
    End Sub
    
    
    

    A première vue ça fonctionne, à un détail près: mes clefs (Item.Key) sont actuellement des STRING.
    J'ai donc essayé de modifier la classe Item en définissant .Key As String,
    mais ça ne fonctionne pas... On dirait que ValueMember de la combobox n'accepte que les Integer (comme si c'était l'Index standard ???)

    Comme tu as l'air de maitriser cette combobox, peut-être as-tu une idée ?

    Merci d'avance

    (je m'absente et ne pourrais pas répondre avant vendredi matin, donc à vendredi)

    Cordialement,


    PS: Pourquoi mon code inséré n'est pas correctement indenté comme le tien ? Je fais pourtant "insérer le bloc de code", puis je choisis le style VbNet...
    Désolé donc que ce ne soit pas plus lisible


    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    • Modifié Golard mercredi 17 février 2010 11:32 remarque sur l'insertion de code dans le message
    mercredi 17 février 2010 11:29
  • Bonjour,

    si tu passes Key As String et modifies le constructeur on peut alors ajouter les items  avec:

    Dim list As New List(Of Item)()
    list.Add(New Item("key1", "Libelle1", ImageList1.Images(0)))
    et on récupère bien "key1"

    Cordialement

    • Marqué comme réponse Golard vendredi 19 février 2010 08:32
    mercredi 17 février 2010 12:55
  • Autant pour moi !!!

    J'avais oublié un "Integer" dans le constructeur...
    Donc effectivement ça marche parfaitement !

    Je vais pouvoir utiliser dans mon projet une combobox standard avec ma classe perso d'Item sans utiliser une dll d'un tiers.

    M E R C I nikho pour tes réponses claires, précises et rapides.

    A bientôt

    Cordialement,
    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    vendredi 19 février 2010 08:31
  • Argh....

    Désolé de revenir à la charge, mais après 2 heures passées, je n'arrive toujours pas à encapsuler cette solution dans une dll (le but étant créer un contrôle qui inclue nativement le code précisé plus haut dans l'évènement DrawItem).

    Voici ce que j'ai fait:
    a) j'ai créé un nouveau projet de type Visual Basic Windows Control Library (je nomme le fichier UserControl-ImageCbobox.vb)
    b) j'ai glissé déposé une combobox dans dans le design
    c) j'ai mis en commentaire la ligne "Inherits System.Windows.Forms.UserControl" dans le fichier .Designer.vb et j'ai ajouté "Inherits System.Windows.Forms.ComboBox" dans le fichier .vb
    d) j'ai écrit le code du DrawItem dans l'évènement de l'objet ajouté au design en ajoutant au commencement "MyBase.OnDrawItem(e)"
    e) j'ai ajouté un fichier de classe au projet pour y créer la classe CollecItem (appelée Item plus haut). Je nomme ce fichier Class-CollecItem.vb

    Au final en utilisant ce contrôle dans mon projet test, rien ne s'affiche dans la combobox...

    Voici le code de mon projet WindowsControlLibrary.

    Le code du fichier UserControl-ImageCbobox.vb:

    Public Class ImageCbobox
    
        Inherits System.Windows.Forms.ComboBox
    
        Public Sub New()
    
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
    
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
    
        End Sub
    
    
        Private Sub ComboBox_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox.DrawItem
    
            MyBase.OnDrawItem(e)
    
            If (e.Index <> -1) Then
    
                'gestion d'une combo associée à objet item
                If TypeOf (ComboBox.DataSource) Is List(Of CollecItem) Then
    
                    'item courant
                    Dim item As CollecItem = CType(ComboBox.Items(e.Index), CollecItem)
    
                    'gestion couleur de fond si item sélectionné : par ex fond gris
                    If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                        e.Graphics.FillRectangle(New SolidBrush(System.Drawing.SystemColors.Highlight), e.Bounds)
                        'dessin libellé
                        e.Graphics.DrawString(item.Display, e.Font, New SolidBrush(System.Drawing.SystemColors.HighlightText), e.Bounds.Left + item.Image.Width, e.Bounds.Top)
                    Else
                        e.DrawBackground()
                        'dessin libellé
                        e.Graphics.DrawString(item.Display, e.Font, New SolidBrush(System.Drawing.SystemColors.WindowText), e.Bounds.Left + item.Image.Width, e.Bounds.Top)
                    End If
    
                    'dessin image
                    e.Graphics.DrawImage(item.Image, e.Bounds.Left, e.Bounds.Top)
    
                    'focus
                    e.DrawFocusRectangle()
                End If
    
            End If
    
        End Sub
    End Class
    

    le code du fichier UserControl-ImageCbobox.Designer.vb (où j'ai juste commenté une ligne):

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class ImageCbobox
        'Inherits System.Windows.Forms.UserControl
    
        'UserControl1 remplace la méthode Dispose pour nettoyer la liste des composants.
        <System.Diagnostics.DebuggerNonUserCode()> _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub
    
        'Requise par le Concepteur Windows Form
        Private components As System.ComponentModel.IContainer
    
        'REMARQUE : la procédure suivante est requise par le Concepteur Windows Form
        'Elle peut être modifiée à l'aide du Concepteur Windows Form.  
        'Ne la modifiez pas à l'aide de l'éditeur de code.
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            Me.ComboBox = New System.Windows.Forms.ComboBox
            Me.SuspendLayout()
            '
            'ComboBox
            '
            Me.ComboBox.FormattingEnabled = True
            Me.ComboBox.Location = New System.Drawing.Point(0, 0)
            Me.ComboBox.Name = "ComboBox"
            Me.ComboBox.Size = New System.Drawing.Size(121, 21)
            Me.ComboBox.TabIndex = 0
            Me.ResumeLayout(False)
    
        End Sub
        Friend WithEvents ComboBox As System.Windows.Forms.ComboBox
    
    End Class
    

    Enfin, le code du fichier Class-CollecItem.vb :

    Public Class CollecItem
    
        Public Sub New(ByVal key As String, ByVal display As String, ByRef image As System.Drawing.Image)
            Me.Key = key
            Me.Display = display
            Me.Image = image
        End Sub
    
    
        Private _key As String
        Public Property Key() As String
            Get
                Return Me._key
            End Get
            Set(ByVal value As String)
                Me._key = value
            End Set
        End Property
    
        Private _display As String
        Public Property Display() As String
            Get
                Return Me._display
            End Get
            Set(ByVal value As String)
                Me._display = value
            End Set
        End Property
    
        Private _image As System.Drawing.Image
        Public Property Image() As Image
            Get
                Return Me._image
            End Get
            Set(ByVal value As System.Drawing.Image)
                Me._image = value
            End Set
        End Property
    
    End Class
    


    Bien sur, c'est mon tout premier composant VbNet... donc ça doit être gros comme une maison !
    Tous les exemples de composants que je trouve sont en C++ et je ne sais pas comment les traduire en vb pour comparer...

    Quelqu'un peut m'aider à arranger ce code ?

    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    vendredi 19 février 2010 11:45
  • Bonjour,
    en fait tu n'as pas besoin d'un projet de type Visual Basic Windows Control Library.

    L'idée c'est bien de faire un héritage de la classe ComboBox et pas de créer un user control contenant une combo.

    - Ajoute un projet de type bibliothèque de classe
    - Ajoute les références qui manqueront ( System.Windows.Form, System.Drawing .. )
    - Renomme la classe créée par défaut et fait la hériter de ComboBox
    - Par rapport au code précédent il modifier la déclaration du DrawItem. Cette fois on ne s'abonne pas à l'événement on surcharge le comportement par défaut

    Public Class ImageCbobox
        Inherits System.Windows.Forms.ComboBox
    
        Public Sub New()
            MyBase.New()
    
            Me.DrawMode = DrawMode.OwnerDrawVariable
    
        End Sub
    
        Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
    
            If (e.Index <> -1) Then
    
                'gestion d'une combo associée à objet item
                If TypeOf (Me.DataSource) Is List(Of Item) Then
    
                    'item courant
                    Dim item As Item = CType(Me.Items(e.Index), Item)
    
                    'gestion couleur de fond si item sélectionné : par ex fond gris
                    If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                        e.Graphics.FillRectangle(System.Drawing.Brushes.Gray, e.Bounds)
                    Else
                        e.DrawBackground()
                    End If
    
                    'dessin image
                    e.Graphics.DrawImage(item.Image, e.Bounds.Left, e.Bounds.Top)
    
                    'dessin libellé
                    e.Graphics.DrawString(item.Display, e.Font, System.Drawing.Brushes.Black, e.Bounds.Left + item.Image.Width, e.Bounds.Top)
    
                    'focus
                    e.DrawFocusRectangle()
                End If
    
            End If
        End Sub
    End Class

    - ajout la classe Item.
    - le projet doit compiler :) et un nouveau composant ImageCboBox doit être présent pour être ajouter quand tu es en mode design dans une winform
    - reste à associer un liste du type List(Of ClassLibrary1.Item)()

    Cordialement






    vendredi 19 février 2010 17:38
  • Merci pour tes éclaircissements !

    J'ai créé ma bibliothèque de classe et ça fonctionne.

    Je vais pouvoir aller de l'avant dans mon projet grâce à toi,

    Cordialement,


    PRECISIONS SUPPLEMENTAIRES:


    J'ai commencé l'implentation dans mon code.

    Pour avoir l'élément sélectionné dans la combo, il y a plus simple que
    MessageBox.Show(CType(ImageCbobox.SelectedItem, ClassLibrary1.Item).Key)

    c'est tout simplement
    MessageBox.Show(ImageCbobox.SelectedValue)

    Pour modifier le SelectedItem par le code (sans passer par l'index), on utilise la même propriété SelectedValue en écriture:
    ImageCbobox.SelectedValue = "key1"

    Cordialement,



    Projet volumineux en cours de migration de Vb6 à VbNet2008 Visual Studio 2008 - VbNET/Vb6(COM)
    • Modifié Golard mardi 23 février 2010 10:10 réponse à ma question !
    lundi 22 février 2010 08:30