none
Where are there the ListView components that can hide any rows? RRS feed

  • Question

  • I want to hide the rows in Microsoft ListView, but it's impossible! where can find the ListView control inherit from Microsoft ListView and can hide the rows? thank you.
    Thursday, August 3, 2017 5:57 AM

Answers

  • In fact, i have already completed some functions using ListView, i dont want to use DataGridView because some features do not exist in it, and i dont want to re-write the code.

    I converted a part of my C++ code to VB.NET
    by using a Vistual ListView with a HDS_FILTERBAR Header and LVN_GETDISPINFO (and a random String array to test)
    It seems to work, but not sure if it will be useful in your case...

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Size = New Size(500, 450)
            Me.CenterToScreen()
    
            Dim nIndex As Integer = 65
            Dim nRepeat As Integer = 0
            For i As Integer = 0 To stringArray.GetUpperBound(0)
                If ((i Mod 26) = 0) Then
                    nIndex = 65
                    nRepeat += 1
                End If
                For j As Integer = 0 To nRepeat - 1
                    stringArray(i, 0) += Chr(nIndex)
                Next
                For n As Integer = 1 To stringArray.GetUpperBound(1)
                    stringArray(i, n) = stringArray(i, 0) + " - col " + Convert.ToString(n + 1)
                Next
                nIndex += 1
            Next
    
            stringArrayDisplay = stringArray.Clone()
    
            hWndListView = CreateWindowEx(0, "SysListView32", "", WS_VISIBLE Or WS_BORDER Or WS_CHILD Or LVS_OWNERDATA Or LVS_REPORT, 0, 0, 0, 0, Me.Handle, 0, 0, IntPtr.Zero)
    
            Dim lvcol As New LVCOLUMN()
            lvcol.mask = LVCF_FMT Or LVCF_TEXT Or LVCF_WIDTH
            lvcol.fmt = LVCFMT_LEFT
            lvcol.cx = 150
    
            Dim sColumnText As String
            For nCol As Integer = 0 To nNbColumns - 1
                sColumnText = String.Format("Column {0}", nCol + 1)
                lvcol.pszText = sColumnText
                Dim pLPARAM As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lvcol))
                Marshal.StructureToPtr(lvcol, pLPARAM, False)
                nCol = SendMessage(hWndListView, LVM_INSERTCOLUMN, nCol, pLPARAM)
                Marshal.FreeHGlobal(pLPARAM)
            Next
    
            hWndHeader = SendMessage(hWndListView, LVM_GETHEADER, 0, 0)
    
            SetWindowLong(hWndHeader, GWL_STYLE, GetWindowLong(hWndHeader, GWL_STYLE) Or HDS_FILTERBAR)
    
            SendMessage(hWndListView, LVM_SETITEMCOUNT, stringArray.GetUpperBound(0), LVSICF_NOINVALIDATEALL)
            SendMessage(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT)
        End Sub
    
        Dim nNbColumns As Integer = 3
        Dim stringArray(100, nNbColumns - 1) As String
        Dim stringArrayDisplay(100, nNbColumns - 1) As String
        Dim hWndListView As IntPtr
        Dim hWndHeader As IntPtr
        Dim sFilterArray(nNbColumns - 1) As String
    
        Const GWL_STYLE As Integer = (-16)
        Const GWL_EXSTYLE As Integer = (-20)
    
        Public Const WS_OVERLAPPED = &H0L
        Public Const WS_BORDER = &H800000L
        Public Const WS_POPUP = &H80000000L
        Public Const WS_CHILD = &H40000000L
        Public Const WS_MINIMIZE = &H20000000L
        Public Const WS_VISIBLE = &H10000000L
        Public Const WS_DISABLED = &H8000000L
    
        <DllImport("user32.dll", SetLastError:=True)>
        Public Shared Function CreateWindowEx(
         ByVal dwExStyle As Integer,
         ByVal lpClassName As String,
         ByVal lpWindowName As String,
         ByVal dwStyle As Integer,
         ByVal x As Integer,
         ByVal y As Integer,
         ByVal nWidth As Integer,
         ByVal nHeight As Integer,
         ByVal hWndParent As IntPtr,
         ByVal hMenu As IntPtr,
         ByVal hInstance As IntPtr,
         ByVal lpParam As IntPtr) As IntPtr
        End Function
    
        Public Shared Function HIWORD(n As Integer) As Integer
            Return (n >> 16) And &HFFFF
        End Function
    
        Public Shared Function LOWORD(n As Integer) As Integer
            Return n And &HFFFF
        End Function
    
        Const GW_HWNDFIRST = 0
        Const GW_HWNDLAST = 1
        Const GW_HWNDNEXT = 2
        Const GW_HWNDPREV = 3
        Const GW_OWNER = 4
        Const GW_CHILD = 5
    
        Const ES_UPPERCASE = &H8
        Const ES_LOWERCASE = &H10
    
        <DllImport("user32.dll")>
        Public Shared Function GetWindow(hWnd As IntPtr, uCmd As UInteger) As IntPtr
        End Function
    
        <DllImport("User32.dll")>
        Private Shared Function MoveWindow(hWnd As IntPtr, X As Integer, Y As Integer, nWidth As Integer, nHeight As Integer, bRepaint As Boolean) As Boolean
        End Function
    
        <DllImport("User32.dll", EntryPoint:="SendMessageW", SetLastError:=True)>
        Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
        End Function
    
        <DllImport("User32.dll", EntryPoint:="SendMessageW")>
        Private Shared Function ItemSendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As HDITEM) As Integer
        End Function
    
        Public Shared Function SetWindowLong(hWnd As IntPtr, nIndex As Integer, dwNewLong As Long) As Integer
            If IntPtr.Size = 4 Then
                Return SetWindowLongPtr32(hWnd, nIndex, dwNewLong)
            End If
            Return SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
        End Function
    
        <DllImport("User32.dll", EntryPoint:="SetWindowLong")>
        Private Shared Function SetWindowLongPtr32(ByVal hWnd As IntPtr, <MarshalAs(UnmanagedType.I4)> nIndex As Integer, ByVal dwNewLong As Integer) As Integer
        End Function
    
        <DllImport("User32.dll", CharSet:=CharSet.Auto, EntryPoint:="SetWindowLongPtr")>
        Public Shared Function SetWindowLongPtr64(hWnd As IntPtr, nIndex As Integer, dwNewLong As Integer) As Integer
        End Function
    
        Public Shared Function GetWindowLong(hWnd As IntPtr, nIndex As Integer) As Integer
            If IntPtr.Size = 4 Then
                Return GetWindowLong32(hWnd, nIndex)
            End If
            Return GetWindowLongPtr64(hWnd, nIndex)
        End Function
    
        <DllImport("User32.dll", EntryPoint:="GetWindowLong", CharSet:=CharSet.Auto)>
        Private Shared Function GetWindowLong32(hWnd As IntPtr, nIndex As Integer) As Integer
        End Function
    
        <DllImport("User32.dll", EntryPoint:="GetWindowLongPtr", CharSet:=CharSet.Auto)>
        Private Shared Function GetWindowLongPtr64(hWnd As IntPtr, nIndex As Integer) As Integer
        End Function
    
        Const WM_SIZE As Long = &H5
        Const WM_NOTIFY As Long = &H4E
        Const WM_SETREDRAW As Long = &HB
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure LVITEM
            Public mask As Integer
            Public iItem As Integer
            Public iSubItem As Integer
            Public state As Integer
            Public stateMask As Integer
            'Public pszText As String
            Public pszText As IntPtr
            Public cchTextMax As Integer
            Public iImage As Integer
            Public lParam As IntPtr
            Public iIndent As Integer
            Public iGroupId As Integer
            Public cColumns As Integer
            ' tile view columns
            Public puColumns As IntPtr
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure NMHDR
            Public hwndFrom As IntPtr
            Public idFrom As Integer
            Public code As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure LVDISPINFO
            Public hdr As NMHDR
            Public item As LVITEM
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure HDITEM
            Public mask As Integer
            Public cxy As Integer
            Public pszText As IntPtr
            Public hbm As IntPtr
            Public cchTextMax As Integer
            Public fmt As Integer
            Public lParam As Integer
            Public iImage As Integer
            Public iOrder As Integer
            Public type As Integer
            Public pvFilter As IntPtr
            Public state As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure NMHEADER
            Public hdr As NMHDR
            Public iItem As Integer
            Public iButton As Integer
            Public pitem As HDITEM
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure HDTEXTFILTER
            Public pszText As String
            Public cchTextMax As Integer
        End Structure
    
    
        Const LVS_ICON As Long = &H0
        Const LVS_REPORT As Long = &H1
        Const LVS_SMALLICON As Long = &H2
        Const LVS_LIST As Long = &H3
        Const LVS_OWNERDATA As Long = &H1000
    
        Const LVS_EX_FULLROWSELECT As Long = &H20
    
        Const LVN_FIRST As Long = (0 - 100)
        Const LVN_GETDISPINFOA As Long = (LVN_FIRST - 50)
        Const LVN_GETDISPINFOW As Long = (LVN_FIRST - 77)
    
        Const LVIF_TEXT As Long = &H1
        Const LVIF_IMAGE As Long = &H2
        Const LVIF_PARAM As Long = &H4
        Const LVIF_STATE As Long = &H8
        Const LVIF_INDENT As Long = &H10
        Const LVIF_NORECOMPUTE As Long = &H800
        Const LVIF_GROUPID As Long = &H100
        Const LVIF_COLUMNS As Long = &H200
    
        Const LVM_FIRST As Long = &H1000
        Const LVM_DELETEALLITEMS As Long = (LVM_FIRST + 9)
        Const LVM_REDRAWITEMS As Long = (LVM_FIRST + 21)
        Const LVM_GETHEADER As Long = (LVM_FIRST + 31)
        Const LVM_GETTOPINDEX As Long = (LVM_FIRST + 39)
        Const LVM_GETCOUNTPERPAGE As Long = (LVM_FIRST + 40)
        Const LVM_SETITEMCOUNT As Long = (LVM_FIRST + 47)
        Const LVM_SETEXTENDEDLISTVIEWSTYLE As Long = (LVM_FIRST + 54)
    
        Const LVM_INSERTCOLUMNA As Long = (LVM_FIRST + 27)
        Const LVM_INSERTCOLUMNW As Long = (LVM_FIRST + 97)
        Const LVM_INSERTCOLUMN As Long = LVM_INSERTCOLUMNW
    
        Const LVSICF_NOINVALIDATEALL As Long = &H1
        Const LVSICF_NOSCROLL As Long = &H2
    
        Const LVCF_FMT = &H1
        Const LVCF_WIDTH = &H2
        Const LVCF_TEXT = &H4
    
        Const LVCFMT_LEFT = &H0
        Const LVCFMT_RIGHT = &H1
        Const LVCFMT_CENTER = &H2
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure LVCOLUMN
            Public mask As Integer
            Public fmt As Integer
            Public cx As Integer
            Public pszText As String
            Public cchTextMax As Integer
            Public iSubItem As Integer
            Public iImage As Integer
            Public iOrder As Integer
        End Structure
    
        Const HDS_FILTERBAR As Long = &H100
    
        Const HDN_FIRST As Long = (0 - 300)
        Const HDN_FILTERCHANGE As Long = (HDN_FIRST - 12)
        Const HDN_BEGINFILTEREDIT As Long = (HDN_FIRST - 14)
        Const HDN_ENDFILTEREDIT As Long = (HDN_FIRST - 15)
    
        Const HDM_FIRST As Long = &H1200
        Const HDM_GETITEMA As Long = (HDM_FIRST + 3)
        Const HDM_GETITEMW As Long = (HDM_FIRST + 11)
    
        Const HDI_WIDTH As Long = &H1
        Const HDI_HEIGHT As Long = HDI_WIDTH
        Const HDI_TEXT As Long = &H2
        Const HDI_FORMAT As Long = &H4
        Const HDI_LPARAM As Long = &H8
        Const HDI_BITMAP As Long = &H10
        Const HDI_IMAGE As Long = &H20
        Const HDI_DI_SETITEM As Long = &H40
        Const HDI_ORDER As Long = &H80
        Const HDI_FILTER As Long = &H100
        Const HDI_STATE As Long = &H200
    
        Const HDF_BITMAP As Long = &H2000
        Const HDF_STRING As Long = &H4000
    
        Const HDFT_ISSTRING As Long = &H0
        Const HDFT_ISNUMBER As Long = &H1
        Const HDFT_ISDATE As Long = &H2
        Const HDFT_HASNOVALUE As Long = &H8000
    
        Protected Overrides Sub WndProc(ByRef m As Message)
            'MyBase.WndProc(m)
            If (m.Msg = WM_NOTIFY) Then
                Dim pnmh As NMHDR = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHDR)), NMHDR)
                If (pnmh.hwndFrom = hWndListView) Then
                    If (pnmh.code = LVN_GETDISPINFOW) Then
                        Dim lpdi As LVDISPINFO = CType(Marshal.PtrToStructure(m.LParam, GetType(LVDISPINFO)), LVDISPINFO)
                        If (lpdi.item.pszText <> IntPtr.Zero) Then
                            Dim sText As String = stringArrayDisplay(lpdi.item.iItem, lpdi.item.iSubItem) + vbNullChar
                            Marshal.Copy(sText, 0, lpdi.item.pszText, sText.Length)
                        End If
                    End If
                End If
                If (pnmh.hwndFrom = hWndHeader) Then
                    If (pnmh.code = HDN_BEGINFILTEREDIT) Then
                        Dim hWndEdit As IntPtr = GetWindow(hWndHeader, GW_CHILD)
                        SetWindowLong(hWndEdit, GWL_STYLE, GetWindowLong(hWndEdit, GWL_STYLE) Or ES_UPPERCASE)
                        ' some wrong data...
                        Dim pnmheader As NMHEADER = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHEADER)), NMHEADER)
                    End If
                    If (pnmh.code = HDN_ENDFILTEREDIT) Then
                        ' some wrong data...
                        Dim pnmheader As NMHEADER = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHEADER)), NMHEADER)
                    End If
                    If (pnmh.code = HDN_FILTERCHANGE) Then
                        Dim pnmheader As NMHEADER = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHEADER)), NMHEADER)
    
                        Dim hdTextfilter As New HDTEXTFILTER()
                        Dim hdItem As New HDITEM()
    
                        hdTextfilter.pszText = New String(New Char(256) {})
                        hdTextfilter.cchTextMax = 256
                        hdItem.mask = HDI_FILTER
                        hdItem.type = HDFT_ISSTRING ' Or HDFT_HASNOVALUE
                        hdItem.pvFilter = Marshal.AllocCoTaskMem(Marshal.SizeOf(hdTextfilter))
                        Marshal.StructureToPtr(hdTextfilter, hdItem.pvFilter, False)
                        Dim nReturn As Integer = ItemSendMessage(pnmh.hwndFrom, HDM_GETITEMW, pnmheader.iItem, hdItem)
                        hdTextfilter = DirectCast(Marshal.PtrToStructure(hdItem.pvFilter, GetType(HDTEXTFILTER)), HDTEXTFILTER)
                        If (hdItem.type = HDFT_ISSTRING) Then
                            sFilterArray(pnmheader.iItem) = hdTextfilter.pszText
                        Else
                            sFilterArray(pnmheader.iItem) = String.Empty
                        End If
                        Marshal.FreeCoTaskMem(hdItem.pvFilter)
    
                        SendMessage(hWndListView, WM_SETREDRAW, False, 0)
                        SendMessage(hWndListView, LVM_DELETEALLITEMS, 0, 0)
                        'SendMessage(hWndListView, LVM_SETITEMCOUNT, 0, 0)
    
                        Array.Clear(stringArrayDisplay, 0, stringArrayDisplay.Length)
                        Dim nItems = 0
                        For i As Integer = 0 To stringArray.GetUpperBound(0)
                            Dim bOK As Boolean = True
                            For n As Integer = 0 To stringArray.GetUpperBound(1)
                                If (sFilterArray(n) <> String.Empty) Then
                                    If (Not stringArray(i, n).Contains(sFilterArray(n))) Then
                                        bOK = False
                                    End If
                                End If
                            Next
                            If (bOK) Then
                                For n As Integer = 0 To stringArray.GetUpperBound(1)
                                    stringArrayDisplay(nItems, n) = stringArray(i, n)
                                Next
                                nItems += 1
                            End If
                        Next
    
                        SendMessage(hWndListView, LVM_SETITEMCOUNT, nItems, LVSICF_NOINVALIDATEALL)
                        'SendMessage(hWndListView, LVM_SETITEMCOUNT, nItems, 0)
                        'Dim nTop As Integer = SendMessage(hWndListView, LVM_GETTOPINDEX, 0, 0)
                        'Dim nPage As Integer = SendMessage(hWndListView, LVM_GETCOUNTPERPAGE, 0, 0) + 1
                        'SendMessage(hWndListView, LVM_REDRAWITEMS, 0, &HFFFFFFFF)
                        'SendMessage(hWndListView, LVM_REDRAWITEMS, nTop, nTop + nPage)
                        SendMessage(hWndListView, WM_SETREDRAW, True, 0)
                    End If
                End If
            ElseIf (m.Msg = WM_SIZE) Then
                MoveWindow(hWndListView, 0, 0, LOWORD(m.LParam), HIWORD(m.LParam), True)
            Else
                MyBase.WndProc(m)
            End If
        End Sub
    End Class
    


    • Edited by Castorix31 Saturday, August 5, 2017 8:31 AM
    • Marked as answer by gaxjyxq Saturday, August 5, 2017 9:44 AM
    Saturday, August 5, 2017 8:28 AM

All replies

  • Sorry, i want to use it on Windows Form...
    Thursday, August 3, 2017 9:26 AM
  • You can use a Virtual ListView to display ony the items you want

    (ListView.VirtualMode Property)

    Thursday, August 3, 2017 9:59 AM
  • I am building the search function for the Listview items, like most Windows search, when type a letter will filter some items and only show the search result, other items will be hidden...
    Thursday, August 3, 2017 10:49 AM
  • Sorry, i want to use it on Windows Form...

    You might want to forget using a ListView control and instead, opt to use a DataGridView control (which is a better control anyway).

    With that, hiding a row is pretty straightforward:

    https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewrow.visible(v=vs.110).aspx


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 3, 2017 10:51 AM
  • I am building the search function for the Listview items, like most Windows search, when type a letter will filter some items and only show the search result, other items will be hidden...

    There's a better way: If you use a DataGridView, you can then use a BindingSource as the DGV's .DataSource.

    To do what you describe, let the BindingSource take care of that:

    https://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.filter(v=vs.110).aspx

    It's not "hiding the row" -- the row isn't there (until you reset the filter).


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 3, 2017 10:54 AM
  • I am building the search function for the Listview items, like most Windows search, when type a letter will filter some items and only show the search result, other items will be hidden...

    As I said, I do this with Virtual ListViews

    or use a DataGridView as Frank L. Smith said, a lot simpler



    • Edited by Castorix31 Thursday, August 3, 2017 11:20 AM
    Thursday, August 3, 2017 10:58 AM
  • I am building the search function for the Listview items, like most Windows search, when type a letter will filter some items and only show the search result, other items will be hidden...

    Have a look at this on StackOverflow:

    https://stackoverflow.com/questions/7786556/how-to-filter-records-in-datagrid-view-and-show-the-selected-record-in-the-datag

    He pretty much describes what you're doing and it uses a DGV along with a BindingSource.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 3, 2017 11:16 AM
  • Probably you are still relying to much on your screen as if it is something likewise word or excel. 

    Try to separate data and presentation. 

    Then your question does not even exist. 

    Don't think that hiding something on screen takes less time than writing it new. It are just pixels, it is no paper.


    Success
    Cor

    Thursday, August 3, 2017 12:42 PM
  • I kind of agree with the others in that a DataGridView would be more appropriate. The ListView is somewhat clunky in this respect, but if you want to give it a shot then see the below link:

    How to: Add Search Capabilities to a ListView Control


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Thursday, August 3, 2017 2:23 PM
  • Hello Castorix31, can you give a simple sample that how to use Virtual ListView to filter the items by a search box? thank you.
               
    5,530                                   
    Points
    Top 5
    Castorix31           
                Joined  Dec 2014           
               

    3

                                                                                                

    10

                                            
    Thursday, August 3, 2017 9:55 PM
  • Hello Castorix31, can you give a simple sample that how to use Virtual ListView to filter the items by a search box? thank you

    My code is in C/C++

    I usually convert it quickly to VB.NET, but it would be too complex in this case (I use dynamic arrays and filters items in LVN_GETDISPINFO, which is a bit different  from MSDN samples with listView1_CacheVirtualItems)

    So use rather a DataGridView as others said...



    • Edited by Castorix31 Friday, August 4, 2017 3:02 AM
    Friday, August 4, 2017 2:25 AM
  • Thank you, i do not want to use DataGridView.
    Friday, August 4, 2017 6:18 AM
  • Thank you, i do not want to use DataGridView.

    Why are you opposed to using a DataGridView?

    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, August 4, 2017 11:14 AM
  • Thank you, i do not want to use DataGridView.

    Maybe. 

    However, do you know that a Listview is a view of items and not a view of rows. You talk about a listview. 

    There is a way to show the listview in another way, the same as with the right pane of file explorer in windows. You can present that in detailview, listview, itemview etc. 

    However, I assume that it is not something you want. 

    https://msdn.microsoft.com/en-us/library/system.windows.forms.listview.view(v=vs.110).aspx

    However, I think you have read somewhere something about vintage VB and the Listview. In those days was only available for rows the MS flexgrid. An impossible thing to handle. 

    Currently there is the already mentioned DataGridView, a control which present flawless rows from collections but also not advisable without any data layer bellow it. 


    Success
    Cor

    Friday, August 4, 2017 12:37 PM
  • In fact, i have already completed some functions using ListView, i dont want to use DataGridView because some features do not exist in it, and i dont want to re-write the code.
    Friday, August 4, 2017 12:48 PM
  • In fact, i have already completed some functions using ListView, i dont want to use DataGridView because some features do not exist in it, and i dont want to re-write the code.

    Please make it obvious who you're talking to - we don't all see this forum the same way.

    *****

    What features are you referring to?


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, August 4, 2017 12:53 PM
  • In fact, i have already completed some functions using ListView, i dont want to use DataGridView because some features do not exist in it, and i dont want to re-write the code.

    I converted a part of my C++ code to VB.NET
    by using a Vistual ListView with a HDS_FILTERBAR Header and LVN_GETDISPINFO (and a random String array to test)
    It seems to work, but not sure if it will be useful in your case...

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Size = New Size(500, 450)
            Me.CenterToScreen()
    
            Dim nIndex As Integer = 65
            Dim nRepeat As Integer = 0
            For i As Integer = 0 To stringArray.GetUpperBound(0)
                If ((i Mod 26) = 0) Then
                    nIndex = 65
                    nRepeat += 1
                End If
                For j As Integer = 0 To nRepeat - 1
                    stringArray(i, 0) += Chr(nIndex)
                Next
                For n As Integer = 1 To stringArray.GetUpperBound(1)
                    stringArray(i, n) = stringArray(i, 0) + " - col " + Convert.ToString(n + 1)
                Next
                nIndex += 1
            Next
    
            stringArrayDisplay = stringArray.Clone()
    
            hWndListView = CreateWindowEx(0, "SysListView32", "", WS_VISIBLE Or WS_BORDER Or WS_CHILD Or LVS_OWNERDATA Or LVS_REPORT, 0, 0, 0, 0, Me.Handle, 0, 0, IntPtr.Zero)
    
            Dim lvcol As New LVCOLUMN()
            lvcol.mask = LVCF_FMT Or LVCF_TEXT Or LVCF_WIDTH
            lvcol.fmt = LVCFMT_LEFT
            lvcol.cx = 150
    
            Dim sColumnText As String
            For nCol As Integer = 0 To nNbColumns - 1
                sColumnText = String.Format("Column {0}", nCol + 1)
                lvcol.pszText = sColumnText
                Dim pLPARAM As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lvcol))
                Marshal.StructureToPtr(lvcol, pLPARAM, False)
                nCol = SendMessage(hWndListView, LVM_INSERTCOLUMN, nCol, pLPARAM)
                Marshal.FreeHGlobal(pLPARAM)
            Next
    
            hWndHeader = SendMessage(hWndListView, LVM_GETHEADER, 0, 0)
    
            SetWindowLong(hWndHeader, GWL_STYLE, GetWindowLong(hWndHeader, GWL_STYLE) Or HDS_FILTERBAR)
    
            SendMessage(hWndListView, LVM_SETITEMCOUNT, stringArray.GetUpperBound(0), LVSICF_NOINVALIDATEALL)
            SendMessage(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT)
        End Sub
    
        Dim nNbColumns As Integer = 3
        Dim stringArray(100, nNbColumns - 1) As String
        Dim stringArrayDisplay(100, nNbColumns - 1) As String
        Dim hWndListView As IntPtr
        Dim hWndHeader As IntPtr
        Dim sFilterArray(nNbColumns - 1) As String
    
        Const GWL_STYLE As Integer = (-16)
        Const GWL_EXSTYLE As Integer = (-20)
    
        Public Const WS_OVERLAPPED = &H0L
        Public Const WS_BORDER = &H800000L
        Public Const WS_POPUP = &H80000000L
        Public Const WS_CHILD = &H40000000L
        Public Const WS_MINIMIZE = &H20000000L
        Public Const WS_VISIBLE = &H10000000L
        Public Const WS_DISABLED = &H8000000L
    
        <DllImport("user32.dll", SetLastError:=True)>
        Public Shared Function CreateWindowEx(
         ByVal dwExStyle As Integer,
         ByVal lpClassName As String,
         ByVal lpWindowName As String,
         ByVal dwStyle As Integer,
         ByVal x As Integer,
         ByVal y As Integer,
         ByVal nWidth As Integer,
         ByVal nHeight As Integer,
         ByVal hWndParent As IntPtr,
         ByVal hMenu As IntPtr,
         ByVal hInstance As IntPtr,
         ByVal lpParam As IntPtr) As IntPtr
        End Function
    
        Public Shared Function HIWORD(n As Integer) As Integer
            Return (n >> 16) And &HFFFF
        End Function
    
        Public Shared Function LOWORD(n As Integer) As Integer
            Return n And &HFFFF
        End Function
    
        Const GW_HWNDFIRST = 0
        Const GW_HWNDLAST = 1
        Const GW_HWNDNEXT = 2
        Const GW_HWNDPREV = 3
        Const GW_OWNER = 4
        Const GW_CHILD = 5
    
        Const ES_UPPERCASE = &H8
        Const ES_LOWERCASE = &H10
    
        <DllImport("user32.dll")>
        Public Shared Function GetWindow(hWnd As IntPtr, uCmd As UInteger) As IntPtr
        End Function
    
        <DllImport("User32.dll")>
        Private Shared Function MoveWindow(hWnd As IntPtr, X As Integer, Y As Integer, nWidth As Integer, nHeight As Integer, bRepaint As Boolean) As Boolean
        End Function
    
        <DllImport("User32.dll", EntryPoint:="SendMessageW", SetLastError:=True)>
        Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
        End Function
    
        <DllImport("User32.dll", EntryPoint:="SendMessageW")>
        Private Shared Function ItemSendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As HDITEM) As Integer
        End Function
    
        Public Shared Function SetWindowLong(hWnd As IntPtr, nIndex As Integer, dwNewLong As Long) As Integer
            If IntPtr.Size = 4 Then
                Return SetWindowLongPtr32(hWnd, nIndex, dwNewLong)
            End If
            Return SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
        End Function
    
        <DllImport("User32.dll", EntryPoint:="SetWindowLong")>
        Private Shared Function SetWindowLongPtr32(ByVal hWnd As IntPtr, <MarshalAs(UnmanagedType.I4)> nIndex As Integer, ByVal dwNewLong As Integer) As Integer
        End Function
    
        <DllImport("User32.dll", CharSet:=CharSet.Auto, EntryPoint:="SetWindowLongPtr")>
        Public Shared Function SetWindowLongPtr64(hWnd As IntPtr, nIndex As Integer, dwNewLong As Integer) As Integer
        End Function
    
        Public Shared Function GetWindowLong(hWnd As IntPtr, nIndex As Integer) As Integer
            If IntPtr.Size = 4 Then
                Return GetWindowLong32(hWnd, nIndex)
            End If
            Return GetWindowLongPtr64(hWnd, nIndex)
        End Function
    
        <DllImport("User32.dll", EntryPoint:="GetWindowLong", CharSet:=CharSet.Auto)>
        Private Shared Function GetWindowLong32(hWnd As IntPtr, nIndex As Integer) As Integer
        End Function
    
        <DllImport("User32.dll", EntryPoint:="GetWindowLongPtr", CharSet:=CharSet.Auto)>
        Private Shared Function GetWindowLongPtr64(hWnd As IntPtr, nIndex As Integer) As Integer
        End Function
    
        Const WM_SIZE As Long = &H5
        Const WM_NOTIFY As Long = &H4E
        Const WM_SETREDRAW As Long = &HB
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure LVITEM
            Public mask As Integer
            Public iItem As Integer
            Public iSubItem As Integer
            Public state As Integer
            Public stateMask As Integer
            'Public pszText As String
            Public pszText As IntPtr
            Public cchTextMax As Integer
            Public iImage As Integer
            Public lParam As IntPtr
            Public iIndent As Integer
            Public iGroupId As Integer
            Public cColumns As Integer
            ' tile view columns
            Public puColumns As IntPtr
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure NMHDR
            Public hwndFrom As IntPtr
            Public idFrom As Integer
            Public code As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure LVDISPINFO
            Public hdr As NMHDR
            Public item As LVITEM
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure HDITEM
            Public mask As Integer
            Public cxy As Integer
            Public pszText As IntPtr
            Public hbm As IntPtr
            Public cchTextMax As Integer
            Public fmt As Integer
            Public lParam As Integer
            Public iImage As Integer
            Public iOrder As Integer
            Public type As Integer
            Public pvFilter As IntPtr
            Public state As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure NMHEADER
            Public hdr As NMHDR
            Public iItem As Integer
            Public iButton As Integer
            Public pitem As HDITEM
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure HDTEXTFILTER
            Public pszText As String
            Public cchTextMax As Integer
        End Structure
    
    
        Const LVS_ICON As Long = &H0
        Const LVS_REPORT As Long = &H1
        Const LVS_SMALLICON As Long = &H2
        Const LVS_LIST As Long = &H3
        Const LVS_OWNERDATA As Long = &H1000
    
        Const LVS_EX_FULLROWSELECT As Long = &H20
    
        Const LVN_FIRST As Long = (0 - 100)
        Const LVN_GETDISPINFOA As Long = (LVN_FIRST - 50)
        Const LVN_GETDISPINFOW As Long = (LVN_FIRST - 77)
    
        Const LVIF_TEXT As Long = &H1
        Const LVIF_IMAGE As Long = &H2
        Const LVIF_PARAM As Long = &H4
        Const LVIF_STATE As Long = &H8
        Const LVIF_INDENT As Long = &H10
        Const LVIF_NORECOMPUTE As Long = &H800
        Const LVIF_GROUPID As Long = &H100
        Const LVIF_COLUMNS As Long = &H200
    
        Const LVM_FIRST As Long = &H1000
        Const LVM_DELETEALLITEMS As Long = (LVM_FIRST + 9)
        Const LVM_REDRAWITEMS As Long = (LVM_FIRST + 21)
        Const LVM_GETHEADER As Long = (LVM_FIRST + 31)
        Const LVM_GETTOPINDEX As Long = (LVM_FIRST + 39)
        Const LVM_GETCOUNTPERPAGE As Long = (LVM_FIRST + 40)
        Const LVM_SETITEMCOUNT As Long = (LVM_FIRST + 47)
        Const LVM_SETEXTENDEDLISTVIEWSTYLE As Long = (LVM_FIRST + 54)
    
        Const LVM_INSERTCOLUMNA As Long = (LVM_FIRST + 27)
        Const LVM_INSERTCOLUMNW As Long = (LVM_FIRST + 97)
        Const LVM_INSERTCOLUMN As Long = LVM_INSERTCOLUMNW
    
        Const LVSICF_NOINVALIDATEALL As Long = &H1
        Const LVSICF_NOSCROLL As Long = &H2
    
        Const LVCF_FMT = &H1
        Const LVCF_WIDTH = &H2
        Const LVCF_TEXT = &H4
    
        Const LVCFMT_LEFT = &H0
        Const LVCFMT_RIGHT = &H1
        Const LVCFMT_CENTER = &H2
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Structure LVCOLUMN
            Public mask As Integer
            Public fmt As Integer
            Public cx As Integer
            Public pszText As String
            Public cchTextMax As Integer
            Public iSubItem As Integer
            Public iImage As Integer
            Public iOrder As Integer
        End Structure
    
        Const HDS_FILTERBAR As Long = &H100
    
        Const HDN_FIRST As Long = (0 - 300)
        Const HDN_FILTERCHANGE As Long = (HDN_FIRST - 12)
        Const HDN_BEGINFILTEREDIT As Long = (HDN_FIRST - 14)
        Const HDN_ENDFILTEREDIT As Long = (HDN_FIRST - 15)
    
        Const HDM_FIRST As Long = &H1200
        Const HDM_GETITEMA As Long = (HDM_FIRST + 3)
        Const HDM_GETITEMW As Long = (HDM_FIRST + 11)
    
        Const HDI_WIDTH As Long = &H1
        Const HDI_HEIGHT As Long = HDI_WIDTH
        Const HDI_TEXT As Long = &H2
        Const HDI_FORMAT As Long = &H4
        Const HDI_LPARAM As Long = &H8
        Const HDI_BITMAP As Long = &H10
        Const HDI_IMAGE As Long = &H20
        Const HDI_DI_SETITEM As Long = &H40
        Const HDI_ORDER As Long = &H80
        Const HDI_FILTER As Long = &H100
        Const HDI_STATE As Long = &H200
    
        Const HDF_BITMAP As Long = &H2000
        Const HDF_STRING As Long = &H4000
    
        Const HDFT_ISSTRING As Long = &H0
        Const HDFT_ISNUMBER As Long = &H1
        Const HDFT_ISDATE As Long = &H2
        Const HDFT_HASNOVALUE As Long = &H8000
    
        Protected Overrides Sub WndProc(ByRef m As Message)
            'MyBase.WndProc(m)
            If (m.Msg = WM_NOTIFY) Then
                Dim pnmh As NMHDR = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHDR)), NMHDR)
                If (pnmh.hwndFrom = hWndListView) Then
                    If (pnmh.code = LVN_GETDISPINFOW) Then
                        Dim lpdi As LVDISPINFO = CType(Marshal.PtrToStructure(m.LParam, GetType(LVDISPINFO)), LVDISPINFO)
                        If (lpdi.item.pszText <> IntPtr.Zero) Then
                            Dim sText As String = stringArrayDisplay(lpdi.item.iItem, lpdi.item.iSubItem) + vbNullChar
                            Marshal.Copy(sText, 0, lpdi.item.pszText, sText.Length)
                        End If
                    End If
                End If
                If (pnmh.hwndFrom = hWndHeader) Then
                    If (pnmh.code = HDN_BEGINFILTEREDIT) Then
                        Dim hWndEdit As IntPtr = GetWindow(hWndHeader, GW_CHILD)
                        SetWindowLong(hWndEdit, GWL_STYLE, GetWindowLong(hWndEdit, GWL_STYLE) Or ES_UPPERCASE)
                        ' some wrong data...
                        Dim pnmheader As NMHEADER = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHEADER)), NMHEADER)
                    End If
                    If (pnmh.code = HDN_ENDFILTEREDIT) Then
                        ' some wrong data...
                        Dim pnmheader As NMHEADER = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHEADER)), NMHEADER)
                    End If
                    If (pnmh.code = HDN_FILTERCHANGE) Then
                        Dim pnmheader As NMHEADER = CType(Marshal.PtrToStructure(m.LParam, GetType(NMHEADER)), NMHEADER)
    
                        Dim hdTextfilter As New HDTEXTFILTER()
                        Dim hdItem As New HDITEM()
    
                        hdTextfilter.pszText = New String(New Char(256) {})
                        hdTextfilter.cchTextMax = 256
                        hdItem.mask = HDI_FILTER
                        hdItem.type = HDFT_ISSTRING ' Or HDFT_HASNOVALUE
                        hdItem.pvFilter = Marshal.AllocCoTaskMem(Marshal.SizeOf(hdTextfilter))
                        Marshal.StructureToPtr(hdTextfilter, hdItem.pvFilter, False)
                        Dim nReturn As Integer = ItemSendMessage(pnmh.hwndFrom, HDM_GETITEMW, pnmheader.iItem, hdItem)
                        hdTextfilter = DirectCast(Marshal.PtrToStructure(hdItem.pvFilter, GetType(HDTEXTFILTER)), HDTEXTFILTER)
                        If (hdItem.type = HDFT_ISSTRING) Then
                            sFilterArray(pnmheader.iItem) = hdTextfilter.pszText
                        Else
                            sFilterArray(pnmheader.iItem) = String.Empty
                        End If
                        Marshal.FreeCoTaskMem(hdItem.pvFilter)
    
                        SendMessage(hWndListView, WM_SETREDRAW, False, 0)
                        SendMessage(hWndListView, LVM_DELETEALLITEMS, 0, 0)
                        'SendMessage(hWndListView, LVM_SETITEMCOUNT, 0, 0)
    
                        Array.Clear(stringArrayDisplay, 0, stringArrayDisplay.Length)
                        Dim nItems = 0
                        For i As Integer = 0 To stringArray.GetUpperBound(0)
                            Dim bOK As Boolean = True
                            For n As Integer = 0 To stringArray.GetUpperBound(1)
                                If (sFilterArray(n) <> String.Empty) Then
                                    If (Not stringArray(i, n).Contains(sFilterArray(n))) Then
                                        bOK = False
                                    End If
                                End If
                            Next
                            If (bOK) Then
                                For n As Integer = 0 To stringArray.GetUpperBound(1)
                                    stringArrayDisplay(nItems, n) = stringArray(i, n)
                                Next
                                nItems += 1
                            End If
                        Next
    
                        SendMessage(hWndListView, LVM_SETITEMCOUNT, nItems, LVSICF_NOINVALIDATEALL)
                        'SendMessage(hWndListView, LVM_SETITEMCOUNT, nItems, 0)
                        'Dim nTop As Integer = SendMessage(hWndListView, LVM_GETTOPINDEX, 0, 0)
                        'Dim nPage As Integer = SendMessage(hWndListView, LVM_GETCOUNTPERPAGE, 0, 0) + 1
                        'SendMessage(hWndListView, LVM_REDRAWITEMS, 0, &HFFFFFFFF)
                        'SendMessage(hWndListView, LVM_REDRAWITEMS, nTop, nTop + nPage)
                        SendMessage(hWndListView, WM_SETREDRAW, True, 0)
                    End If
                End If
            ElseIf (m.Msg = WM_SIZE) Then
                MoveWindow(hWndListView, 0, 0, LOWORD(m.LParam), HIWORD(m.LParam), True)
            Else
                MyBase.WndProc(m)
            End If
        End Sub
    End Class
    


    • Edited by Castorix31 Saturday, August 5, 2017 8:31 AM
    • Marked as answer by gaxjyxq Saturday, August 5, 2017 9:44 AM
    Saturday, August 5, 2017 8:28 AM
  • Thank you.
    Saturday, August 5, 2017 9:44 AM
  • Thank you.

    And you think changing your current code for this is less work than using a DataGridView, which was the problem you wrote?


    Success
    Cor

    Saturday, August 5, 2017 10:25 AM
  • ListView has soem features, for example, View Mode, Sort, Icon...
    Saturday, August 5, 2017 12:21 PM