Thanks, but I am not trying to capture the column.text which would give
me the text appearing in the header of the column. I am trying to
capture the entire ColumnHeader and assign it to a new custom created
class ColHeader. ColHeader should inherit ColumnHeader and then add the
ascending property to it to use for sorting.
The expected result is that I should be able to sort the listview in
ascending or descending order based on column by clicking the column
header.
The actual result is the CastType error: An unhandled exception of type
'System.InvalidCastException' occurred in testprogram.exe
ColHeader is defined with the following code:
Public Class ColHeader
Inherits ColumnHeader
Public ascending As Boolean
Public Sub New(ByVal [Text] As String, ByVal width As Integer, ByVal
align As HorizontalAlignment, ByVal asc As Boolean)
Me.Text = [Text]
Me.Width = width
Me.TextAlign = align
Me.ascending = asc
End Sub
End Class
Then in the column click event we have:
Private Sub lvwItemList_ColumnClick(ByVal sender As Object, ByVal e As
System.Windows.Forms.ColumnClickEventArgs) Handles
lvwItemList.ColumnClick
' Create an instance of the ColHeader class.
Dim clickedCol As ColHeader = CType(Me.lvwItemList.Columns(e.Column),
ColHeader)
' Set the ascending property to sort in the opposite order.
clickedCol.ascending = Not clickedCol.ascending
' Get the number of items in the list.
Dim numItems As Integer = Me.lvwItemList.Items.Count
' Turn off display while data is repoplulated.
Me.lvwItemList.BeginUpdate()
' Populate an ArrayList with a SortWrapper of each list item.
Dim SortArray As New ArrayList
Dim i As Integer
For i = 0 To numItems - 1
SortArray.Add(New SortWrapper(Me.lvwItemList.Items(i), e.Column))
Next i
' Sort the elements in the ArrayList using a new instance of the
SortComparer
' class. The parameters are the starting index, the length of the
range to sort,
' and the IComparer implementation to use for comparing elements.
Note that
' the IComparer implementation (SortComparer) requires the sort
' direction for its constructor; true if ascending, othwise false.
SortArray.Sort(0, SortArray.Count, New
SortWrapper.SortComparer(clickedCol.ascending))
' Clear the list, and repopulate with the sorted items.
Me.lvwItemList.Items.Clear()
Dim z As Integer
For z = 0 To numItems - 1
Me.lvwItemList.Items.Add(CType(SortArray(z),
SortWrapper).sortItem)
Next z
' Turn display back on.
Me.lvwItemList.EndUpdate()
End Sub
The SortWrapper is defined as:
' An instance of the SortWrapper class is created for
'each item and added to the ArrayList for sorting.
Public Class SortWrapper
Friend sortItem As ListViewItem
Friend sortColumn As Integer
' A SortWrapper requires the item and the index of the clicked
column.
Public Sub New(ByVal Item As ListViewItem, ByVal iColumn As Integer)
sortItem = Item
sortColumn = iColumn
End Sub
' Text property for getting the text of an item.
Public ReadOnly Property [Text]() As String
Get
Return sortItem.SubItems(sortColumn).Text
End Get
End Property
' Implementation of the IComparer
' interface for sorting ArrayList items.
Public Class SortComparer
Implements IComparer
Private ascending As Boolean
' Constructor requires the sort order;
' true if ascending, otherwise descending.
Public Sub New(ByVal asc As Boolean)
Me.ascending = asc
End Sub
' Implemnentation of the IComparer:Compare
' method for comparing two objects.
Public Function [Compare](ByVal x As Object, ByVal y As Object)
As Integer Implements IComparer.Compare
Dim xItem As SortWrapper = CType(x, SortWrapper)
Dim yItem As SortWrapper = CType(y, SortWrapper)
Dim xText As String =
xItem.sortItem.SubItems(xItem.sortColumn).Text
Dim yText As String =
yItem.sortItem.SubItems(yItem.sortColumn).Text
Return xText.CompareTo(yText) * IIf(Me.ascending, 1, -1)
End Function
End Class
End Class
All of this is direct from the quickstart tutorial. All I changed was
the name of the listview control.
James Lysaght
CType(Me.lvwItemList.Columns(e.Column)
Your statement seems incomplete (i.e. I'd expect a compile time error)
In any case no cast is required. Assuming a listview with columns if
you place this is in the ColumnClick event handler it should work
Me.Text = lvwItemList.Columns(e.Column).Text
If you are asking for something else please show the full code with
expected and actual results
Cheers
Daniel
--
http://www.danielmoth.com/Blog/
Ok, I have been debugging and all I find is that the error definitely
occurs in the line:
CType(Me.lvwItemList.Columns(e.Column)
I am clicking on the column header of the listview control to trigger
this code. It is direct form the Quickstart but I cannot figure out
what the problem is. How would I check that is in fact a Header
object? I understand the select case function, but what property will
tell me if it is a header object? and since I am clinking the header
wouldn't it have to be a header object?
James Lysaght
In that event, does e have several types of objects that it can
potentially be (Header, Row, Footer, etc)? You may need to make sure
you check that it is in fact a Header object before trying to cast
it. Typically this is done with the use of a switch block (select
case for vb).
Thanks,
Matt
OK
I checked the archives on sorting a listview control and from there
I read the quickstart tutorial. I
duplicated the code from the tutorial, thinking I understood it
fairly well,
and modified as necessary such as changing the name of the listview
control
to the name I used for my listview control.
On the following line:
Dim clickedCol As ColHeader =
CType(Me.lvwItemList.Columns(e.Column),
ColHeader)
I get this error:
An unhandled exception of type 'System.InvalidCastException'
occurred in
testprogram.exe
What the heck does that mean?
ColHeader is defined with the following code:
Public Class ColHeader
Inherits ColumnHeader
Public ascending As Boolean
Public Sub New(ByVal [text] As String, ByVal width As
Integer, ByVal
align As HorizontalAlignment, ByVal asc As Boolean)
Me.Text = [text]
Me.Width = width
Me.TextAlign = align
Me.ascending = asc
End Sub
End Class
James