none
Second ComboBox DrawItem in DropDownList RRS feed

  • Question

  • Hi, I'm Maz.

    I found ComboxBox DrawItem Event when I searched for a way to change backcolor of ComboBox. I learned that I cannot change backcolor in detail in DropDown or Simple style. So I could change the color the way I want with DrawItem Event. But I have two comboboxes and items of the second is automatically changed by the selecteditem of the first one. My question is here.

    I can't trigger the second DrawItem Envent(ComboBox2_DrawItem). How can I do that?

    Public Class Form1
    
        Private animals1() As String
        Dim SelectedItemIndex As Integer
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
            animals1 = New String() {"", "Elephant", "Crocodile", "lion"}
            ComboBox1.DataSource = animals1
    
            ComboBox2.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox2.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
        Private animals2() As String
        Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
            SelectedItemIndex = ComboBox1.SelectedIndex
            Select Case SelectedItemIndex
                Case 1
                    animals2 = New String() {"", "1", "2", "3"}
                    ComboBox2.DataSource = animals2
                Case 2
                    animals2 = New String() {"", "a", "b", "c"}
                    ComboBox2.DataSource = animals2
                Case 3
                    animals2 = New String() {"", "1a", "2b", "3c"}
                    ComboBox2.DataSource = animals2
            End Select
        End Sub
    
        Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
            Dim myFont As System.Drawing.Font = ComboBox1.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals1(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
    
        Private Sub ComboBox2_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)
            Dim myFont As System.Drawing.Font = ComboBox2.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals2(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
    End Class
    

    In ComboBox2_DrawItem sub, if I start with adding 'Handler ComboBox2.DrawItem', the program is failed.

    I'm waiting for your response. Thanks. 

    Sunday, June 11, 2017 8:35 PM

Answers

  • Hello,

    Try the following, note DrawMode in the load event.

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        comboBox1.DrawMode = DrawMode.OwnerDrawFixed
        AddHandler comboBox1.DrawItem, AddressOf DrawIt
    End Sub
    
    Private Sub DrawIt(sender As Object, e As DrawItemEventArgs)
        Dim index As Integer = If(e.Index >= 0, e.Index, 0)
        Dim brush = Brushes.Black
        e.DrawBackground()
        e.Graphics.DrawString(comboBox1.Items(index).ToString(), e.Font, brush, e.Bounds, StringFormat.GenericDefault)
        e.DrawFocusRectangle()
    End Sub


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by mazia21 Monday, June 12, 2017 12:04 PM
    Sunday, June 11, 2017 10:44 PM
    Moderator
  • Hi, I'm Maz.

    I found ComboxBox DrawItem Event when I searched for a way to change backcolor of ComboBox. I learned that I cannot change backcolor in detail in DropDown or Simple style. So I could change the color the way I want with DrawItem Event. But I have two comboboxes and items of the second is automatically changed by the selecteditem of the first one. My question is here.

    I can't trigger the second DrawItem Envent(ComboBox2_DrawItem). How can I do that?

    Public Class Form1
    
        Private animals1() As String
        Dim SelectedItemIndex As Integer
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
            animals1 = New String() {"", "Elephant", "Crocodile", "lion"}
            ComboBox1.DataSource = animals1
    
            ComboBox2.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox2.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
        Private animals2() As String
        Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
            SelectedItemIndex = ComboBox1.SelectedIndex
            Select Case SelectedItemIndex
                Case 1
                    animals2 = New String() {"", "1", "2", "3"}
                    ComboBox2.DataSource = animals2
                Case 2
                    animals2 = New String() {"", "a", "b", "c"}
                    ComboBox2.DataSource = animals2
                Case 3
                    animals2 = New String() {"", "1a", "2b", "3c"}
                    ComboBox2.DataSource = animals2
            End Select
        End Sub
    
        Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
            Dim myFont As System.Drawing.Font = ComboBox1.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals1(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
    
        Private Sub ComboBox2_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)
            Dim myFont As System.Drawing.Font = ComboBox2.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals2(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
    End Class

    In ComboBox2_DrawItem sub, if I start with adding 'Handler ComboBox2.DrawItem', the program is failed.

    I'm waiting for your response. Thanks. 

    Hi

    Here is my take on it. Allows setting of Focus Text Colour and both BackGround Colour and ForeGround Colour for Combobox1 and ComboBox2.

    ' Form1 with ComboBox1
    ' and ComboBox2
    Option Strict On
    Option Explicit On
    Public Class Form1
        ' define backcolor, forecolor for CB items
        Dim CBback As Color = Color.Yellow
        Dim CBfore As Color = Color.Red

        ' define selected item forecolor
        Dim FocusCol As Color = Color.White
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

            ComboBox1.DrawMode = DrawMode.OwnerDrawFixed
            AddHandler ComboBox1.DrawItem, AddressOf OwnerDraw

            ComboBox2.DrawMode = DrawMode.OwnerDrawFixed
            AddHandler ComboBox2.DrawItem, AddressOf OwnerDraw
        End Sub
        Private Sub OwnerDraw(sender As Object, e As DrawItemEventArgs) Handles ComboBox1.DrawItem, ComboBox2.DrawItem
            Dim cb As ComboBox = DirectCast(sender, ComboBox)
            e.DrawBackground()
            If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                e.Graphics.DrawString(cb.Items(e.Index).ToString(), e.Font, New SolidBrush(FocusCol), e.Bounds)
                e.DrawFocusRectangle()
            Else
                e.Graphics.FillRectangle(New SolidBrush(CBback), e.Bounds)
                e.Graphics.DrawString(cb.Items(e.Index).ToString(), e.Font, New SolidBrush(CBfore), e.Bounds)
            End If
        End Sub
    End Class



    Regards Les, Livingston, Scotland




    • Edited by leshay Monday, June 12, 2017 12:38 AM amended for second CB
    • Marked as answer by mazia21 Monday, June 12, 2017 12:04 PM
    Sunday, June 11, 2017 11:43 PM

All replies

  • Hello,

    Try the following, note DrawMode in the load event.

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        comboBox1.DrawMode = DrawMode.OwnerDrawFixed
        AddHandler comboBox1.DrawItem, AddressOf DrawIt
    End Sub
    
    Private Sub DrawIt(sender As Object, e As DrawItemEventArgs)
        Dim index As Integer = If(e.Index >= 0, e.Index, 0)
        Dim brush = Brushes.Black
        e.DrawBackground()
        e.Graphics.DrawString(comboBox1.Items(index).ToString(), e.Font, brush, e.Bounds, StringFormat.GenericDefault)
        e.DrawFocusRectangle()
    End Sub


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by mazia21 Monday, June 12, 2017 12:04 PM
    Sunday, June 11, 2017 10:44 PM
    Moderator
  • Hi, I'm Maz.

    I found ComboxBox DrawItem Event when I searched for a way to change backcolor of ComboBox. I learned that I cannot change backcolor in detail in DropDown or Simple style. So I could change the color the way I want with DrawItem Event. But I have two comboboxes and items of the second is automatically changed by the selecteditem of the first one. My question is here.

    I can't trigger the second DrawItem Envent(ComboBox2_DrawItem). How can I do that?

    Public Class Form1
    
        Private animals1() As String
        Dim SelectedItemIndex As Integer
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
            animals1 = New String() {"", "Elephant", "Crocodile", "lion"}
            ComboBox1.DataSource = animals1
    
            ComboBox2.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox2.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
        Private animals2() As String
        Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
            SelectedItemIndex = ComboBox1.SelectedIndex
            Select Case SelectedItemIndex
                Case 1
                    animals2 = New String() {"", "1", "2", "3"}
                    ComboBox2.DataSource = animals2
                Case 2
                    animals2 = New String() {"", "a", "b", "c"}
                    ComboBox2.DataSource = animals2
                Case 3
                    animals2 = New String() {"", "1a", "2b", "3c"}
                    ComboBox2.DataSource = animals2
            End Select
        End Sub
    
        Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
            Dim myFont As System.Drawing.Font = ComboBox1.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals1(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
    
        Private Sub ComboBox2_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)
            Dim myFont As System.Drawing.Font = ComboBox2.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals2(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
    End Class

    In ComboBox2_DrawItem sub, if I start with adding 'Handler ComboBox2.DrawItem', the program is failed.

    I'm waiting for your response. Thanks. 

    Hi

    Here is my take on it. Allows setting of Focus Text Colour and both BackGround Colour and ForeGround Colour for Combobox1 and ComboBox2.

    ' Form1 with ComboBox1
    ' and ComboBox2
    Option Strict On
    Option Explicit On
    Public Class Form1
        ' define backcolor, forecolor for CB items
        Dim CBback As Color = Color.Yellow
        Dim CBfore As Color = Color.Red

        ' define selected item forecolor
        Dim FocusCol As Color = Color.White
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

            ComboBox1.DrawMode = DrawMode.OwnerDrawFixed
            AddHandler ComboBox1.DrawItem, AddressOf OwnerDraw

            ComboBox2.DrawMode = DrawMode.OwnerDrawFixed
            AddHandler ComboBox2.DrawItem, AddressOf OwnerDraw
        End Sub
        Private Sub OwnerDraw(sender As Object, e As DrawItemEventArgs) Handles ComboBox1.DrawItem, ComboBox2.DrawItem
            Dim cb As ComboBox = DirectCast(sender, ComboBox)
            e.DrawBackground()
            If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
                e.Graphics.DrawString(cb.Items(e.Index).ToString(), e.Font, New SolidBrush(FocusCol), e.Bounds)
                e.DrawFocusRectangle()
            Else
                e.Graphics.FillRectangle(New SolidBrush(CBback), e.Bounds)
                e.Graphics.DrawString(cb.Items(e.Index).ToString(), e.Font, New SolidBrush(CBfore), e.Bounds)
            End If
        End Sub
    End Class



    Regards Les, Livingston, Scotland




    • Edited by leshay Monday, June 12, 2017 12:38 AM amended for second CB
    • Marked as answer by mazia21 Monday, June 12, 2017 12:04 PM
    Sunday, June 11, 2017 11:43 PM
  • I can't trigger the second DrawItem Envent(ComboBox2_DrawItem). How can I do that?

    Your event handler is missing the Handles clause:  

    Private Sub ComboBox2_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)Handles ComboBox2.DrawItem

    Or, make one method that handles both events:

    Private Sub ComboBox_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem, ComboBox2.DrawItem 


    Sunday, June 11, 2017 11:46 PM
  • Hi mazia21,

    I modify your code, please refer to.

    After you selected item in the combobox1, you could add ComboBox2.DrawItem event in ComboBox1_SelectedIndexChanged event.

    Private animals1() As String
        Dim SelectedItemIndex As Integer
        Private animals2() As String
    
        Private Sub Form12_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            
            ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
            animals1 = New String() {"", "Elephant", "Crocodile", "lion"}
            ComboBox1.DataSource = animals1
    
            ComboBox2.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
            ComboBox2.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
        
        Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
            SelectedItemIndex = ComboBox1.SelectedIndex
            Select Case SelectedItemIndex
                Case 1
                    animals2 = New String() {"", "1", "2", "3"}
                    ComboBox2.DataSource = animals2
                    AddHandler ComboBox2.DrawItem, AddressOf DrawItem
    
                Case 2
                    animals2 = New String() {"", "a", "b", "c"}
                    ComboBox2.DataSource = animals2
                    AddHandler ComboBox2.DrawItem, AddressOf DrawItem
                Case 3
                    animals2 = New String() {"", "1a", "2b", "3c"}
                    ComboBox2.DataSource = animals2
                    AddHandler ComboBox2.DrawItem, AddressOf DrawItem
            End Select
    
        End Sub
    
        Private Sub ComboBox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ComboBox1.DrawItem
            Dim myFont As System.Drawing.Font = ComboBox1.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals1(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
        End Sub
        Private Sub DrawItem(sender As Object, e As DrawItemEventArgs)
            Dim myFont As System.Drawing.Font = ComboBox2.Font
            Dim TextColor As New System.Drawing.Color
    
            TextColor = System.Drawing.Color.Black
    
            Dim myBrush As SolidBrush = New SolidBrush(TextColor)
    
            e.DrawBackground()
            e.Graphics.DrawString(animals2(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
            e.DrawFocusRectangle()
    
        End Sub

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 12, 2017 7:47 AM
    Moderator
  • Hi, Karen.

    Good to see you again.

    As the last time, your simple and clear answer is very helpful to me. It seemed that I couldn't distinguish between 'Call myComboBox_DrawItem()' and 'AddHandler myComboBox.DrawItem, AddressOf ...'. I just tried something with the former.

    Monday, June 12, 2017 10:05 AM
  • Hi, Les.

    I thought it's possible to make two DrawItem subs into one. But I didn't know something specific. With Karen's advice, your take is a nice example.

    Public Class Form1 Private animals() As String Dim SelectedItemIndex As Integer Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load ComboBox1.DrawMode = DrawMode.OwnerDrawFixed ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList animals = New String() {"", "Elephant", "Crocodile", "lion"} ComboBox1.DataSource = animals AddHandler ComboBox1.DrawItem, AddressOf ComboBox_DrawItem ComboBox2.DrawMode = DrawMode.OwnerDrawFixed ComboBox2.DropDownStyle = ComboBoxStyle.DropDownList End Sub Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox1.SelectedIndexChanged SelectedItemIndex = ComboBox1.SelectedIndex Select Case SelectedItemIndex Case 0 animals = New String() {""} Case 1 animals = New String() {"", "1", "2", "3"} Case 2 animals = New String() {"", "a", "b", "c"} Case 3 animals = New String() {"", "1a", "2b", "3c"} End Select

    ComboBox2.DataSource=animals
    AddHandler ComboBox2.DrawItem, AddressOf ComboBox_DrawItem

    End Sub Private Sub ComboBox_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles ComboBox1.DrawItem, ComboBox2.DrawItem Dim cb As ComboBox = DirectCast(sender, ComboBox) Dim myFont As Font = ComboBox1.Font Dim TextColor As New Color TextColor = Color.Black Dim myBrush As SolidBrush = New SolidBrush(TextColor) e.DrawBackground() e.Graphics.DrawString(cb.Items(e.Index), myFont, myBrush, New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)) e.DrawFocusRectangle() End Sub End Class

    Thanks a lot.


    • Edited by mazia21 Monday, June 12, 2017 10:24 AM
    Monday, June 12, 2017 10:18 AM
  • Hi, Cherry.

    Thanks for the friendly demonstration. My edited one is the same as yours.


    • Edited by mazia21 Monday, June 12, 2017 12:13 PM
    Monday, June 12, 2017 12:12 PM