Search code examples
.netvb.netlistviewimagelist

ListView spacing issue with View: List in WinForms


I have a ListView in View: List mode.

My issue is spacing per. I just have the images and I want a horizontal scroll.

The issue is this:

Screenshot of issue

Huge gaps between the images. When Iw as using View: LargeIcons or Tile mode, there was also gaps, HOWEVER, this was resolved using LVM_SETICONSPACING. However tile/largeicons are vertical scrolling, which I didn't want.

So there's two things I can do but not sure how to achieve it. 1. Figure out how to fix the spacing in list mode. 2. Make LargeIcons/Tile mode scroll horizontally.

I'll attach some of the coding that handles the listview:

Here is the icon spacing that works with tile/large icons:

<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)>
Private Shared Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Param) As Int32
End Function

<StructLayout(LayoutKind.Explicit)>
Private Structure Param
    <FieldOffset(0)> Public LoWord As Int16
    <FieldOffset(2)> Public HiWord As Int16
End Structure

Private Const LVM_FIRST As Integer = &H1000
Private Const LVM_SETICONSPACING As Integer = LVM_FIRST + 53

Public Sub SetListviewIconSpacing(lv As ListView, ByVal x As Int16, ByVal y As Int16)
    ' The LOWORD specifies the distance, in pixels, to set between icons on the x-axis. 
    ' The HIWORD specifies the distance, in pixels, to set between icons on the y-axis.
    Dim lparam As Param = New Param With {.LoWord = x, .HiWord = y}
    SendMessage(lv.Handle, LVM_SETICONSPACING, 0, lparam)
    lv.Refresh()
End Sub

Here is the general coding to add images using a imagelist:

Dim img As Image
Dim imgList As ImageList = New ImageList()
Dim listItem As ListViewItem
'''SetListviewIconSpacing(lstViewAH, 101, 103)
imgList.ColorDepth = ColorDepth.Depth16Bit
imgList.ImageSize = New Size(92, 92)
lstViewAH.StateImageList = imgList
lstViewAH.LargeImageList = imgList
lstViewAH.SmallImageList = imgList
For i As Integer = 0 To arrX.Count - 1
    img = Image.FromFile(CharactersFolder & "000" & arrX(i).ToString() & ".jpg")
    imgList.Images.Add("itemImageKey" & i, img)
    listItem = New ListViewItem("", "itemImageKey" & i)
    listItem.UseItemStyleForSubItems = False
    listItem.Tag = arrX(i)
    lstViewAH.Items.Add(listItem)
Next

Any ideas?


Solution

  • Simple way using FlowLayoutPanel is:

        FlowLayoutPanel1.SuspendLayout()
        FlowLayoutPanel1.AutoScroll = False
        For i As Integer = 0 To arrX.Count - 1
            Dim newImage As New DoubleBufferImage
            newImage.Load(CharactersFolder & "000" & arrX(i).ToString() & ".jpg")
            newImage.Tag = arrX(i).ToString()
            newImage.Width = 96
            newImage.Height = 96
            FlowLayoutPanel1.Controls.Add(newImage)
        Next
        FlowLayoutPanel1.AutoScroll = True
        FlowLayoutPanel1.ResumeLayout()
    

    You can also load the images with AddRange but I was assuming holding an array is heavier on memory. The speed is quite fast so it wasn't a problem. I disabled AutoScroll because autoscroll takes time recalculating and enable it back afterwards. Seemed to work well and has horizontal scrollbars like I wanted.

    A note: Adding ALOT of controls in debug mode is SLOW. This is not the case in a non-debug/release mode EXE out of VS.