Option Strict On
Option Explicit On
Imports System.Windows.Forms
Public Class ListViewScroll
Inherits System.Windows.Forms.ListView
'SCROLL CONSTANTS
Private Const SBM_SETSCROLLINFO As Integer = &HE9
Private Const WM_HSCROLL As Integer = &H115
Private Const WM_VSCROLL As Integer = &H114
'COLUMN RESIZE CONSTANTS
Private Const WM_COLUMNRESIZE As Integer = 78
'EVENTS
Public Event Scroll(ByVal sender As Object, ByVal e As EventArgs)
Public Event ColumnsResized(ByVal sender As Object)
'PRIVATE VARS
Private mSortOrder As SortOrder = SortOrder.None
Private mSortColumnIndex As Integer = 0
Private mAllowSort As Boolean = True
Protected Sub OnScroll()
RaiseEvent Scroll(Me, EventArgs.Empty)
End Sub
Protected Overridable Sub OnColumnHeaderResized()
RaiseEvent ColumnsResized(Me)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_HSCROLL Or m.Msg = WM_VSCROLL Or m.Msg = SBM_SETSCROLLINFO Then
OnScroll()
ElseIf m.Msg = WM_COLUMNRESIZE Then
OnColumnHeaderResized()
End If
End Sub
Public Property AllowColumnSorting() As Boolean
Get
Return mAllowSort
End Get
Set(ByVal Value As Boolean)
mAllowSort = Value
End Set
End Property
Protected Overrides Sub OnColumnClick(ByVal e As System.Windows.Forms.ColumnClickEventArgs)
If Me.Items.Count = 0 Then Exit Sub
If Not mAllowSort Then Exit Sub
If e.Column = mSortColumnIndex Then
Select Case Me.Sorting
Case SortOrder.None, SortOrder.Descending
Me.Sorting = SortOrder.Ascending
Case Else
Me.Sorting = SortOrder.Descending
End Select
Else
Me.Sorting = SortOrder.Ascending
End If
mSortColumnIndex = e.Column
Dim Sorter As ListViewSorter
Select Case GetColumnType(e.Column)
Case "DATE"
Sorter = New ListViewSorter(e.Column, "DATE", Me.Sorting)
Case "NUMBER"
Sorter = New ListViewSorter(e.Column, "NUMBER", Me.Sorting)
Case Else
Sorter = New ListViewSorter(e.Column, "TEXT", Me.Sorting)
End Select
Me.ListViewItemSorter = Sorter
End Sub
Private Function GetColumnType(ByVal i As Integer) As String
Try
Date.Parse(Me.Items(0).SubItems(i).Text)
Return "DATE"
Catch ex As FormatException
Try
Double.Parse(Me.Items(0).SubItems(i).Text)
Return "NUMBER"
Catch exc As FormatException
Return "TEXT"
End Try
End Try
End Function
Private Class ListViewSorter : Implements System.Collections.IComparer
Public SortIndex As Integer
Private mSortString As String
Private mSortOrder As SortOrder
Public Sub New(ByVal SortIndex As Integer, ByVal DataType As String, ByVal MySortOrder As SortOrder)
Me.SortIndex = SortIndex
mSortString = DataType
mSortOrder = MySortOrder
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim LVI1 As ListViewItem
Dim LVI2 As ListViewItem
LVI1 = CType(x, ListViewItem)
LVI2 = CType(y, ListViewItem)
Select Case mSortString
Case "DATE"
If mSortOrder = SortOrder.Ascending Then
Return Date.Compare(Date.Parse(LVI1.SubItems(SortIndex).Text), Date.Parse(LVI2.SubItems(SortIndex).Text))
Else
Return (Date.Compare(Date.Parse(LVI1.SubItems(SortIndex).Text), Date.Parse(LVI2.SubItems(SortIndex).Text)) * -1)
End If
Case "NUMBER"
Dim N1 As Double = Double.Parse(LVI1.SubItems(SortIndex).Text)
Dim N2 As Double = Double.Parse(LVI2.SubItems(SortIndex).Text)
If mSortOrder = SortOrder.Ascending Then
Return N1.CompareTo(N2)
Else
Return (N1.CompareTo(N2) * -1)
End If
Case Else
If mSortOrder = SortOrder.Ascending Then
Return String.Compare(LVI1.SubItems(SortIndex).Text, LVI2.SubItems(SortIndex).Text)
Else
Return (String.Compare(LVI1.SubItems(SortIndex).Text, LVI2.SubItems(SortIndex).Text) * -1)
End If
End Select
End Function
End Class
End Class