none
VB.Net Display Image In Listview Subitems With Details Setting... RRS feed

  • Question

  • I'm not sure how to select a .PNG image to bring into a specific column or subitem in VB.NET. Here is an example of where I would like to implement the image:

    I'm trying to get a PotOfGold.PNG image right next to the "Extremely Easy" (just to the left of it) into the fourth column every time that a row contains "Extremely Easy". How would I accomplish this in VB.Net? Thanks...

    Edit:

    Oh and here is the code that I currently have:

    ListView1.Items.Add("This is a test", 0)

    • Edited by TeachMe Tuesday, October 28, 2014 9:56 PM
    Tuesday, October 28, 2014 9:29 PM

Answers

  • Wow! Thank you Iron! My friend, could you please help me out with sizing of the image as well? I would like to make it a little bit bigger. Thanks again though! :)

     You`re welcome.  8)

     The only ways i know of to make the image larger is to do one of two things. Make the Font larger which would make each row taller and the image would be drawn larger too, or you can add an ImageList to the project and assign it to the ListView`s SmallImageList. Set the ImageList.ImageSize to the size you want the image. That will automatically set the height of the rows to be able to fit the image in. Then just change the DrawImage method to draw the image from the ImageList.

     I have changed my code around a little in the DrawSubItem event sub to correct the way the strings are drawn so, i am posting the new code here.  8)

    Public Class Form1
        'Create a new imagelist and set the image size to the size you want.
        Private ImgList As New ImageList With {.ImageSize = New Size(24, 24)}
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ImgList.Images.Add(My.Resources.BluePlus) 'Add the Image to the ImageList
    
            ListView1.HideSelection = True
            ListView1.FullRowSelect = True
            ListView1.CheckBoxes = True
            ListView1.OwnerDraw = True
            ListView1.SmallImageList = ImgList 'Set the ListView`s SmallImageList to the ImgList
    
            'This code is just to add a few test items to the listview
            Dim dif() As String = {"Too Difficult", "Relatively Easy", "Extremely Easy", "Relatively Easy"}
            For x As Integer = 0 To 3
                Dim lvi As New ListViewItem("Bracelet " & x.ToString)
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add(dif(x))
                ListView1.Items.Add(lvi)
            Next
        End Sub
    
        Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
            e.DrawDefault = True
        End Sub
    
        Private Sub ListView1_DrawSubItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
            Using txtbrsh As New SolidBrush(e.SubItem.ForeColor)
                If ListView1.SelectedIndices.Contains(e.ItemIndex) And ListView1.Focused Then
                    e.Graphics.FillRectangle(New SolidBrush(Color.FromKnownColor(KnownColor.Highlight)), e.Bounds)
                    txtbrsh.Color = Color.White
                End If
                If e.Item.SubItems(3) Is e.SubItem Then
                    e.DrawDefault = False
                    Using sf As New StringFormat With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center, .FormatFlags = StringFormatFlags.NoWrap, .Trimming = StringTrimming.EllipsisCharacter}
                        If e.SubItem.Text = "Extremely Easy" Then
                            e.Graphics.DrawImage(ImgList.Images(0), e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
                        End If
                        Dim rb As New Rectangle(e.Bounds.X + e.Bounds.Height, e.Bounds.Y, e.Bounds.Width - e.Bounds.Height, e.Bounds.Height)
                        e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, txtbrsh, rb, sf)
                    End Using
                Else
                    e.DrawDefault = True
                End If
            End Using
        End Sub
    End Class
    

      This is with the ImageSize set to 24x24.


    If you say it can`t be done then i`ll try it

    • Proposed as answer by Youjun TangModerator Monday, November 3, 2014 7:49 AM
    • Marked as answer by TeachMe Saturday, November 8, 2014 10:01 PM
    Saturday, November 1, 2014 10:08 PM
  • Hi,

     The listview was only designed to show an image for the ListViewItem which in your case would be the first column in your ListView. If you want to show an image in one of the SubItems then you have to set the ListView`s OwnerDraw property to True and handle the DrawColumnHeader event and the DrawSubItem event of the ListView to draw it using some Graphics methods.

     Here is a simple example that will draw an image next to any item in the 4th column of the listview that has the Text "Extremely Easy". I added my (.png) image (BluePlus) to the applications resources for this example.

     I am sure you will have some bugs that may need to be worked out. You may even have to handle drawing all the Items instead of just the last SubItem of each ListViewItem to get everything to work the way you want. That includes the CheckBoxes too. It can get a little involved if you are not familiar with using the Graphics methods.   8)

    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ListView1.HideSelection = True
            ListView1.FullRowSelect = True
            ListView1.CheckBoxes = True
            ListView1.OwnerDraw = True
    
            'This code is just to add a few test items to the listview
            Dim dif() As String = {"Too Difficult", "Relatively Easy", "Extremely Easy", "Relatively Easy"}
            For x As Integer = 0 To 3
                Dim lvi As New ListViewItem("Bracelet " & x.ToString)
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add(dif(x))
                ListView1.Items.Add(lvi)
            Next
        End Sub
    
        Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
            e.DrawDefault = True
        End Sub
    
        Private Sub ListView1_DrawSubItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
            Using txtbrsh As New SolidBrush(e.SubItem.ForeColor)
                If ListView1.SelectedIndices.Contains(e.ItemIndex) And ListView1.Focused Then
                    e.Graphics.FillRectangle(New SolidBrush(Color.FromKnownColor(KnownColor.Highlight)), e.Bounds)
                    txtbrsh.Color = Color.White
                End If
                Using sf As New StringFormat With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center, .FormatFlags = StringFormatFlags.NoWrap, .Trimming = StringTrimming.EllipsisCharacter}
                    If e.Item.SubItems(3) Is e.SubItem Then
                        e.DrawDefault = False
                        Dim rb As New Rectangle(e.Bounds.X + e.Bounds.Height, e.Bounds.Y, e.Bounds.Width + e.Bounds.Height, e.Bounds.Height)
                        If e.SubItem.Text = "Extremely Easy" Then
                            e.Graphics.DrawImage(My.Resources.BluePlus, e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
                        End If
                        e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, txtbrsh, rb, sf)
                    Else
                        e.DrawDefault = True
                    End If
                End Using
            End Using
        End Sub
    End Class
    


    If you say it can`t be done then i`ll try it

    • Proposed as answer by Frank L. Smith Saturday, November 1, 2014 8:14 PM
    • Marked as answer by TeachMe Saturday, November 8, 2014 10:01 PM
    Wednesday, October 29, 2014 10:25 AM

All replies

  • Hello??? Is anybody here???
    Wednesday, October 29, 2014 2:45 AM
  • Hi TeachMe,

    According to your description, you'd like to add a Image next to the string in the listview item.

    I suggest you redrawing the Item of ListView.

    First you should change the OwnDraw property of the ListView to True. Then use the DrawSubItem and DrawColumnHeader event handler to redraw the item.

    Here is a sample for you.

    Private Sub ListView1_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
            If e.ColumnIndex = 2 Then
                Dim im As Image = Image.FromFile("YOUR IMAGE PATH")
                Dim location As Point  = Me.listView1.Items(e.ItemIndex).SubItems(e.ColumnIndex).Bounds.Location
                e.Graphics.DrawImage(im, Location)
                e.Graphics.DrawString("hi", Me.Font, new SolidBrush(Color.Black), new PointF(location.X + 20, location.Y))
                'Here 20 is the width of your image.
                e.DrawFocusRectangle(Me.ListView1.Items(e.ItemIndex).SubItems(e.ColumnIndex).Bounds)
            Else
                e.DrawText()
            End If
        End Sub
    
        Private Sub ListView1_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
            e.DrawText()
        End Sub
    
    

    If you have any other concern regarding this issue, please feel free to let me know.

    Best regards,
    Youjun Tang



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, October 29, 2014 10:06 AM
    Moderator
  • Hi,

     The listview was only designed to show an image for the ListViewItem which in your case would be the first column in your ListView. If you want to show an image in one of the SubItems then you have to set the ListView`s OwnerDraw property to True and handle the DrawColumnHeader event and the DrawSubItem event of the ListView to draw it using some Graphics methods.

     Here is a simple example that will draw an image next to any item in the 4th column of the listview that has the Text "Extremely Easy". I added my (.png) image (BluePlus) to the applications resources for this example.

     I am sure you will have some bugs that may need to be worked out. You may even have to handle drawing all the Items instead of just the last SubItem of each ListViewItem to get everything to work the way you want. That includes the CheckBoxes too. It can get a little involved if you are not familiar with using the Graphics methods.   8)

    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ListView1.HideSelection = True
            ListView1.FullRowSelect = True
            ListView1.CheckBoxes = True
            ListView1.OwnerDraw = True
    
            'This code is just to add a few test items to the listview
            Dim dif() As String = {"Too Difficult", "Relatively Easy", "Extremely Easy", "Relatively Easy"}
            For x As Integer = 0 To 3
                Dim lvi As New ListViewItem("Bracelet " & x.ToString)
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add(dif(x))
                ListView1.Items.Add(lvi)
            Next
        End Sub
    
        Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
            e.DrawDefault = True
        End Sub
    
        Private Sub ListView1_DrawSubItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
            Using txtbrsh As New SolidBrush(e.SubItem.ForeColor)
                If ListView1.SelectedIndices.Contains(e.ItemIndex) And ListView1.Focused Then
                    e.Graphics.FillRectangle(New SolidBrush(Color.FromKnownColor(KnownColor.Highlight)), e.Bounds)
                    txtbrsh.Color = Color.White
                End If
                Using sf As New StringFormat With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center, .FormatFlags = StringFormatFlags.NoWrap, .Trimming = StringTrimming.EllipsisCharacter}
                    If e.Item.SubItems(3) Is e.SubItem Then
                        e.DrawDefault = False
                        Dim rb As New Rectangle(e.Bounds.X + e.Bounds.Height, e.Bounds.Y, e.Bounds.Width + e.Bounds.Height, e.Bounds.Height)
                        If e.SubItem.Text = "Extremely Easy" Then
                            e.Graphics.DrawImage(My.Resources.BluePlus, e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
                        End If
                        e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, txtbrsh, rb, sf)
                    Else
                        e.DrawDefault = True
                    End If
                End Using
            End Using
        End Sub
    End Class
    


    If you say it can`t be done then i`ll try it

    • Proposed as answer by Frank L. Smith Saturday, November 1, 2014 8:14 PM
    • Marked as answer by TeachMe Saturday, November 8, 2014 10:01 PM
    Wednesday, October 29, 2014 10:25 AM
  • Wow! Thank you Iron! My friend, could you please help me out with sizing of the image as well? I would like to make it a little bit bigger. Thanks again though! :)
    Saturday, November 1, 2014 7:01 PM
  • Wow! Thank you Iron! My friend, could you please help me out with sizing of the image as well? I would like to make it a little bit bigger. Thanks again though! :)

     You`re welcome.  8)

     The only ways i know of to make the image larger is to do one of two things. Make the Font larger which would make each row taller and the image would be drawn larger too, or you can add an ImageList to the project and assign it to the ListView`s SmallImageList. Set the ImageList.ImageSize to the size you want the image. That will automatically set the height of the rows to be able to fit the image in. Then just change the DrawImage method to draw the image from the ImageList.

     I have changed my code around a little in the DrawSubItem event sub to correct the way the strings are drawn so, i am posting the new code here.  8)

    Public Class Form1
        'Create a new imagelist and set the image size to the size you want.
        Private ImgList As New ImageList With {.ImageSize = New Size(24, 24)}
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ImgList.Images.Add(My.Resources.BluePlus) 'Add the Image to the ImageList
    
            ListView1.HideSelection = True
            ListView1.FullRowSelect = True
            ListView1.CheckBoxes = True
            ListView1.OwnerDraw = True
            ListView1.SmallImageList = ImgList 'Set the ListView`s SmallImageList to the ImgList
    
            'This code is just to add a few test items to the listview
            Dim dif() As String = {"Too Difficult", "Relatively Easy", "Extremely Easy", "Relatively Easy"}
            For x As Integer = 0 To 3
                Dim lvi As New ListViewItem("Bracelet " & x.ToString)
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add(dif(x))
                ListView1.Items.Add(lvi)
            Next
        End Sub
    
        Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
            e.DrawDefault = True
        End Sub
    
        Private Sub ListView1_DrawSubItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
            Using txtbrsh As New SolidBrush(e.SubItem.ForeColor)
                If ListView1.SelectedIndices.Contains(e.ItemIndex) And ListView1.Focused Then
                    e.Graphics.FillRectangle(New SolidBrush(Color.FromKnownColor(KnownColor.Highlight)), e.Bounds)
                    txtbrsh.Color = Color.White
                End If
                If e.Item.SubItems(3) Is e.SubItem Then
                    e.DrawDefault = False
                    Using sf As New StringFormat With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center, .FormatFlags = StringFormatFlags.NoWrap, .Trimming = StringTrimming.EllipsisCharacter}
                        If e.SubItem.Text = "Extremely Easy" Then
                            e.Graphics.DrawImage(ImgList.Images(0), e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
                        End If
                        Dim rb As New Rectangle(e.Bounds.X + e.Bounds.Height, e.Bounds.Y, e.Bounds.Width - e.Bounds.Height, e.Bounds.Height)
                        e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, txtbrsh, rb, sf)
                    End Using
                Else
                    e.DrawDefault = True
                End If
            End Using
        End Sub
    End Class
    

      This is with the ImageSize set to 24x24.


    If you say it can`t be done then i`ll try it

    • Proposed as answer by Youjun TangModerator Monday, November 3, 2014 7:49 AM
    • Marked as answer by TeachMe Saturday, November 8, 2014 10:01 PM
    Saturday, November 1, 2014 10:08 PM
  • Wow! Thank you Iron! My friend, could you please help me out with sizing of the image as well? I would like to make it a little bit bigger. Thanks again though! :)

     You`re welcome.  8)

     The only ways i know of to make the image larger is to do one of two things. Make the Font larger which would make each row taller and the image would be drawn larger too, or you can add an ImageList to the project and assign it to the ListView`s SmallImageList. Set the ImageList.ImageSize to the size you want the image. That will automatically set the height of the rows to be able to fit the image in. Then just change the DrawImage method to draw the image from the ImageList.

     I have changed my code around a little in the DrawSubItem event sub to correct the way the strings are drawn so, i am posting the new code here.  8)

    Public Class Form1
        'Create a new imagelist and set the image size to the size you want.
        Private ImgList As New ImageList With {.ImageSize = New Size(24, 24)}
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ImgList.Images.Add(My.Resources.BluePlus) 'Add the Image to the ImageList
    
            ListView1.HideSelection = True
            ListView1.FullRowSelect = True
            ListView1.CheckBoxes = True
            ListView1.OwnerDraw = True
            ListView1.SmallImageList = ImgList 'Set the ListView`s SmallImageList to the ImgList
    
            'This code is just to add a few test items to the listview
            Dim dif() As String = {"Too Difficult", "Relatively Easy", "Extremely Easy", "Relatively Easy"}
            For x As Integer = 0 To 3
                Dim lvi As New ListViewItem("Bracelet " & x.ToString)
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add("Number")
                lvi.SubItems.Add(dif(x))
                ListView1.Items.Add(lvi)
            Next
        End Sub
    
        Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
            e.DrawDefault = True
        End Sub
    
        Private Sub ListView1_DrawSubItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
            Using txtbrsh As New SolidBrush(e.SubItem.ForeColor)
                If ListView1.SelectedIndices.Contains(e.ItemIndex) And ListView1.Focused Then
                    e.Graphics.FillRectangle(New SolidBrush(Color.FromKnownColor(KnownColor.Highlight)), e.Bounds)
                    txtbrsh.Color = Color.White
                End If
                If e.Item.SubItems(3) Is e.SubItem Then
                    e.DrawDefault = False
                    Using sf As New StringFormat With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center, .FormatFlags = StringFormatFlags.NoWrap, .Trimming = StringTrimming.EllipsisCharacter}
                        If e.SubItem.Text = "Extremely Easy" Then
                            e.Graphics.DrawImage(ImgList.Images(0), e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
                        End If
                        Dim rb As New Rectangle(e.Bounds.X + e.Bounds.Height, e.Bounds.Y, e.Bounds.Width - e.Bounds.Height, e.Bounds.Height)
                        e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, txtbrsh, rb, sf)
                    End Using
                Else
                    e.DrawDefault = True
                End If
            End Using
        End Sub
    End Class
    

      This is with the ImageSize set to 24x24.


    If you say it can`t be done then i`ll try it

    Thanks again my friend, you're AWESOME!!!
    Saturday, November 8, 2014 10:01 PM