It is not at all clear what you want exactly. Like how can I basically make my Listview very customized is vague and very broad (and why you didn't get an answer you liked).
A picture is nice, but words describing the desired appearance would have been better. Given a picture to scrutinize, there is no way to know what is Important and what is just there...because. I assume every detail is important based on very customized. Additionally:
Listview/Listbox Pick one: they are very different controls.
- The little 2 pixel margin between items would be very problematic for a
ListView, so I scratched the LV1.
- Why are all the items gray in the first image? That typically indicates disabled, so can items be disabled (such as when there is no program data for a given channel)?
- What does the gray box on "FOX" represent? Is it the selected item? Is it the HotLight/MouseHover item?
ListBox/ListView items do not normally light up when the mouse passes over (the LV can when HotTracking is true, but thats only when the mouse is over the Item not subitem(s)).
- Is the darker gray for that box rectangle an absolute color? The
HotLight and Selected coloring is usually handled by the OS (==Operating System) respecting the theme and color choices of the user. Is this gadget supposed to ignore those, or is your theme using some shade of gray for Highlight ?
I measured the elements in the first image carefully to get some metrics, then made guesses on the answers to the above.
No Code Solution
Use a Button. Since the user will presumably click one of these to select a desired channel, a Button makes more sense than a ListView (much more). You can display an image on a Button along with text, and use the FlatAppearance properties to style it how you want. Use the Tag to track the channel ID or the index of the related channel in the collection.
Finally, use the MouseHover and MouseLeave events to manipulate FlatAppearance.BorderSize and FlatAppearance.BorderColor to get very close to the first image in the question:

They reside in an scrolling Panel. The panel width is just a bit wider than the control to avoid the horizontal scrollbar. As for the buttons, the HotLight border (???) is around the entire control rather than just the text. Not what your picture shows you want, but on the other hand, there is nothing involved beyond some standard properties and a little event handling code (5-6 lines).
Image ListBox
An ownerdraw ListBox will get you a bit closer to what you want, but ultimately this just makes it look like a ListBox that has Buttons in it.
Place a ListBox on the form, and set these properties:
- DrawMode = OwnerDrawFixed
- IntegralHeight = False
- Itemheight = 64 (this is based on the fact that the images are 60x60 in the first image)
- Set the BackColor to ControlLight or {233,233,233} for that exact shade of gray as desired.
As mentioned, ListBox items do not normally light up when the mouse is over them, so we need some code to track that (like a Button):
Private mouseItem As Int32 = -1
Private Sub lbChannels_MouseMove(sender As Object,
e As MouseEventArgs) Handles lbChannels.MouseMove
Dim ndx = lbChannels.IndexFromPoint(e.Location)
' test to avoid millions of paints
If ndx <> mouseItem Then
If mouseItem <> -1 Then
' invalidate/redraw the OLD itemrect
lbChannels.Invalidate(lbChannels.GetItemRectangle(mouseItem))
End If
mouseItem = ndx
' invalidate/redraw the NEW itemrect
lbChannels.Invalidate(lbChannels.GetItemRectangle(mouseItem))
End If
End Sub
Private Sub lbChannels_MouseLeave(sender As Object,
e As EventArgs) Handles lbChannels.MouseLeave
If mouseItem <> -1 Then
' get rect for what wont be the hot item in a tick
Dim rect = lbChannels.GetItemRectangle(mouseItem)
'lbChannels.Invalidate()
mouseItem = -1 ' no longer Hot
lbChannels.Invalidate(rect)
End If
End Sub
Updated to minimize flickering by redrawing just the items which changed.
I did not use the MouseHover event because that fires later, resulting the small (but no where near a second) delay mentioned. MouseMove also makes it easier to get the mouse location.
IImageItem
Based on comments, you want to auto-generate items based on some other data in the app. Rather than assume what that class looks like and to make this easy to implement and applicable to any class, this will use an interface:
Public Interface IImageItem
Property ID As String ' ???
Property ItemImage As Image
Property Text As String
End Interface
The draw code will require that interface be implemented so it can use those properties to draw your items. Id is an extra one to allow a way to link which ListBox item is selected or clicked from the collection (only needed if you add items to the ListBox -- not recommended). It could be extended to include an Enabled property to draw those differently, if needed. You'd implement this interface on your collection items class thusly:
Public Class ChannelItem
Implements IImageItem
Public Property ItemImage As Image Implements IImageItem.ItemImage
Public Property Text As String Implements IImageItem.Text
Public Property ID As String Implements IImageItem.ID
' + your existing properties
Public Sub New(txt As String, img As Image, key As String)
Text = txt
ItemImage = img
ID = key
End Sub
Public Overrides Function ToString() As String
Return Text
End Function
End Class
Note: ChannelItem is my demo version of whatever class you are using to track the channels. Just type Implements IImageItem on your class, press enter and the IDE will add the properties, set them before adding items to your collection.
DrawItem Code
Private Sub lbChannels_DrawItem(sender As Object,
e As DrawItemEventArgs) Handles lbChannels.DrawItem
Dim lb As ListBox = lbChannels
If e.Index < 0 Then
TextRenderer.DrawText(e.Graphics, "", lb.Font, e.Bounds, lb.ForeColor)
Return
End If
Dim iItem As IImageItem
If TypeOf (lb.Items(e.Index)) Is IImageItem Then
iItem = DirectCast(lb.Items(e.Index), IImageItem)
Else
TextRenderer.DrawText(e.Graphics, lb.Items(e.Index).ToString,
lb.Font, e.Bounds, lb.ForeColor)
Return
End If
Dim imgRect As Rectangle = Rectangle.Empty
Dim txtRect As Rectangle
' calc
If iItem.ItemImage IsNot Nothing Then
imgRect = New Rectangle(e.Bounds.X + 1, e.Bounds.Y + 1,
iItem.ItemImage.Width + 2, iItem.ItemImage.Height + 2)
End If
' GetTextExtent
Dim sz = TextRenderer.MeasureText(" " & iItem.Text, lb.Font)
txtRect = New Rectangle(iItem.ItemImage.Width + 4, e.Bounds.Y + 1,
(e.Bounds.Width - iItem.ItemImage.Width) - 8,
e.Bounds.Height - 2)
' Draw Big Box around the text portion
If e.Index = mouseItem Then
Using pR As New Pen(SystemColors.ControlDark, 2),
brB As New SolidBrush(SystemColors.Window)
e.Graphics.DrawRectangle(pR, txtRect)
txtRect.Inflate(-1, -1)
e.Graphics.FillRectangle(brB, txtRect)
End Using
ElseIf (e.State.HasFlag(DrawItemState.Selected)) Then
' ToDo: modify for whatever is desired for the selected item
' this is a guess/example
Using pR As New Pen(SystemColors.Highlight, 2),
brB As New SolidBrush(SystemColors.Window)
e.Graphics.DrawRectangle(pR, txtRect)
txtRect.Inflate(-1, -1)
e.Graphics.FillRectangle(brB, txtRect)
End Using
Else
' could use a channel specific color for each BG
' just extend IImageItem
e.DrawBackground()
End If
If iItem.ItemImage IsNot Nothing Then
e.Graphics.DrawImage(iItem.ItemImage, imgRect)
End If
' recalc TR for where the text really goes
txtRect = New Rectangle(iItem.ItemImage.Width + 4, e.Bounds.Y + 1,
sz.Width + 2, e.Bounds.Height - 0)
TextRenderer.DrawText(e.Graphics, iItem.Text, lb.Font, txtRect, lb.ForeColor)
End Sub
Again, it is not clear whether the darker gray box for "FOX" represents the SelectedItem,HotLight`/Hover item or even disabled. The code shows how/where to box the text for the first 2 cases. Modify as needed.
Usage
' a collection of ChannelItem objects (which implement IImageItem)
Dim channels As New List(Of ChannelItem)
' my fake data
channels.Add(New ChannelItem("More 4", My.Resources.SO_LVImg01, "M4"))
channels.Add(New ChannelItem("Channel 4", My.Resources.SO_LVImg02, "4"))
channels.Add(New ChannelItem("RTE One", My.Resources.SO_LVImg03, "RET1"))
channels.Add(New ChannelItem("FOX", My.Resources.SO_LVImg04, "Fox"))
...
It is all pretty straightforward, just substitute your class for ChannelItem (it must implement IImageItem). Rather than copy items into the items collection, you can use that collection as the DataSource:
lbChannels.DataSource = channels
SelectedValue will be a ChannelItem object boxed as System.Object, cast it back to get at all the related data such as a URL or Now Playing text.
The result:


In this case, the selected item has a SystemColor.Hightlight box (blue in my case), and the item the mouse is over has a gray box. There even appears to be the little 2px gap between each item as in the original image. This is the result of the image height being a bit less than the ItemHeight used.
Putting a border on the things would elide the need to do mouse over highlighting.
UserControl
If you want (nearly) total control over how these pseudo buttons appear, you should probably build a UserControl. Using a Label and PictureBox and just the normal events you could get it to do almost anything you want. You can slap one together in about 20 mins:

The Channel UserControls are contained in an autoscrolling Panel. They are basically a custom button, but allows you a great deal of control over the layout, behavior and appearance. Best of all, each would have its own distinct Click event.
1 The reason there are no gaps between items in the LV or LB is to make it easier for users to select an item. A gutter or gap opens the chance that the user could click there and get no result. Or depending on the implementation, your code would crash using a bad index.
ListView1.Columns.Item(1).Width = 5or whatever value suits youlistview1.SuspendLayoutat the beginning of the sub, and at the end, addlistview1.ResumeLayout- replacinglistview1with the name of your ListView of course