I might as well post my ListView class I wrote.

Its far from done, but it does the things I need it to do at the moment that the regular listview doesn't do.

These include
- Column Sorting on text, date, or numeric values
- added a Scroll event that fires when you scroll the listview (why did they leave that out?)
- Added a ColumnsResized event that will fire if you resize a column (good if you have custom controls like a textbox in the listview...)

I wrote a lot of this when i was less familiar with .net, so if anyone wants to make any suggestions please do. It does work fine though.
VB Code:
  1. Option Strict On
  2. Option Explicit On
  3.  
  4. Imports System.Windows.Forms
  5. Public Class ListViewScroll
  6.     Inherits System.Windows.Forms.ListView
  7.  
  8.     'SCROLL CONSTANTS
  9.     Private Const SBM_SETSCROLLINFO As Integer = &HE9
  10.     Private Const WM_HSCROLL As Integer = &H115
  11.     Private Const WM_VSCROLL As Integer = &H114
  12.     'COLUMN RESIZE CONSTANTS
  13.     Private Const WM_COLUMNRESIZE As Integer = 78
  14.  
  15.  
  16.     'EVENTS
  17.     Public Event Scroll(ByVal sender As Object, ByVal e As EventArgs)
  18.     Public Event ColumnsResized(ByVal sender As Object)
  19.  
  20.     'PRIVATE VARS
  21.     Private mSortOrder As SortOrder = SortOrder.None
  22.     Private mSortColumnIndex As Integer = 0
  23.     Private mAllowSort As Boolean = True
  24.  
  25.  
  26.     Protected Sub OnScroll()
  27.  
  28.         RaiseEvent Scroll(Me, EventArgs.Empty)
  29.  
  30.     End Sub
  31.  
  32.     Protected Overridable Sub OnColumnHeaderResized()
  33.         RaiseEvent ColumnsResized(Me)
  34.     End Sub
  35.     Protected Overrides Sub WndProc(ByRef m As System.windows.Forms.Message)
  36.  
  37.         MyBase.WndProc(m)
  38.         If m.Msg = WM_HSCROLL Or m.Msg = WM_VSCROLL Or m.Msg = SBM_SETSCROLLINFO Then
  39.  
  40.             OnScroll()
  41.  
  42.         ElseIf m.Msg = WM_COLUMNRESIZE Then
  43.  
  44.             OnColumnHeaderResized()
  45.  
  46.         End If
  47.  
  48.     End Sub
  49.  
  50.  
  51.     Public Property AllowColumnSorting() As Boolean
  52.         Get
  53.             Return mAllowSort
  54.         End Get
  55.         Set(ByVal Value As Boolean)
  56.             mAllowSort = Value
  57.         End Set
  58.     End Property
  59.     Protected Overrides Sub OnColumnClick(ByVal e As System.Windows.Forms.ColumnClickEventArgs)
  60.         If Me.Items.Count = 0 Then Exit Sub
  61.         If Not mAllowSort Then Exit Sub
  62.  
  63.         If e.Column = mSortColumnIndex Then
  64.             Select Case Me.Sorting
  65.                 Case SortOrder.None, SortOrder.Descending
  66.                     Me.Sorting = SortOrder.Ascending
  67.                 Case Else
  68.                     Me.Sorting = SortOrder.Descending
  69.             End Select
  70.         Else
  71.             Me.Sorting = SortOrder.Ascending
  72.         End If
  73.  
  74.         mSortColumnIndex = e.Column
  75.  
  76.         Dim Sorter As ListViewSorter
  77.  
  78.         Select Case GetColumnType(e.Column)
  79.             Case "DATE"
  80.                 Sorter = New ListViewSorter(e.Column, "DATE", Me.Sorting)
  81.             Case "NUMBER"
  82.                 Sorter = New ListViewSorter(e.Column, "NUMBER", Me.Sorting)
  83.             Case Else
  84.                 Sorter = New ListViewSorter(e.Column, "TEXT", Me.Sorting)
  85.         End Select
  86.  
  87.         Me.ListViewItemSorter = Sorter
  88.     End Sub
  89.  
  90.     Private Function GetColumnType(ByVal i As Integer) As String
  91.         Try
  92.             Date.Parse(Me.Items(0).SubItems(i).Text)
  93.             Return "DATE"
  94.         Catch ex As FormatException
  95.             Try
  96.                 Double.Parse(Me.Items(0).SubItems(i).Text)
  97.                 Return "NUMBER"
  98.             Catch exc As FormatException
  99.                 Return "TEXT"
  100.             End Try
  101.         End Try
  102.     End Function
  103.     Private Class ListViewSorter : Implements System.Collections.IComparer
  104.  
  105.         Public SortIndex As Integer
  106.         Private mSortString As String
  107.         Private mSortOrder As SortOrder
  108.  
  109.         Public Sub New(ByVal SortIndex As Integer, ByVal DataType As String, ByVal MySortOrder As SortOrder)
  110.  
  111.             Me.SortIndex = SortIndex
  112.             mSortString = DataType
  113.             mSortOrder = MySortOrder
  114.         End Sub
  115.  
  116.         Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
  117.  
  118.  
  119.             Dim LVI1 As ListViewItem
  120.             Dim LVI2 As ListViewItem
  121.  
  122.             LVI1 = CType(x, ListViewItem)
  123.             LVI2 = CType(y, ListViewItem)
  124.  
  125.             Select Case mSortString
  126.                 Case "DATE"
  127.                     If mSortOrder = SortOrder.Ascending Then
  128.                         Return Date.Compare(Date.Parse(LVI1.SubItems(SortIndex).Text), Date.Parse(LVI2.SubItems(SortIndex).Text))
  129.                     Else
  130.                         Return (Date.Compare(Date.Parse(LVI1.SubItems(SortIndex).Text), Date.Parse(LVI2.SubItems(SortIndex).Text)) * -1)
  131.                     End If
  132.                 Case "NUMBER"
  133.                     Dim N1 As Double = Double.Parse(LVI1.SubItems(SortIndex).Text)
  134.                     Dim N2 As Double = Double.Parse(LVI2.SubItems(SortIndex).Text)
  135.                     If mSortOrder = SortOrder.Ascending Then
  136.                         Return N1.CompareTo(N2)
  137.                     Else
  138.                         Return (N1.CompareTo(N2) * -1)
  139.                     End If
  140.                 Case Else
  141.                     If mSortOrder = SortOrder.Ascending Then
  142.                         Return String.Compare(LVI1.SubItems(SortIndex).Text, LVI2.SubItems(SortIndex).Text)
  143.                     Else
  144.                         Return (String.Compare(LVI1.SubItems(SortIndex).Text, LVI2.SubItems(SortIndex).Text) * -1)
  145.                     End If
  146.             End Select
  147.  
  148.         End Function
  149.  
  150.     End Class
  151. End Class