how do I debug error: InvalidCastTypeException

  • Thread starter Thread starter JamesL
  • Start date Start date
J

JamesL

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
 
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 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


ME said:
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


JamesL said:
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
 
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/


JamesL said:
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


ME said:
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


JamesL said:
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
 
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


Daniel Moth said:
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/


JamesL said:
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


ME said:
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
 
I do not see where you adding ColHeader. You have to initiate and add
ColHeader and not ColumnHeader:

lvwItemList.Columns.Add(new ColHeader())


--
Sergey Bogdanov
http://www.sergeybogdanov.com

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
 
I found the quickstart you are talking about (you provided no link):
http://samples.gotdotnet.com/quicks...amework/samples/ListViewSort/ListViewSort.src

See how in the ctor the code show explicit addition of ColHeader objects
(not the default ColumnHeader which the designer will do if you use the UI).
Are you doing the same? Show us all the code...

Cheers
Daniel
--
http://www.danielmoth.com/Blog/


JamesL said:
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


Daniel Moth said:
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/


JamesL said:
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
 
AH HA!!!! That's It!!!!

You hit it right there! I used the UI to add my column headers, I need to
add them in code so I get ColHeader objects instead...

I will experiment with that, I am sure that is the problem. It is obvious
to me now! Admittedly, I am feeling a little red in the face at the moment.
I should have caught that. Thanks a ton!

Sorry about forgetting to include the link to the quickstart: irresponsible
omission on my part. Thanks for looking it up!

James Lysaght

Daniel Moth said:
I found the quickstart you are talking about (you provided no link):
http://samples.gotdotnet.com/quicks...amework/samples/ListViewSort/ListViewSort.src

See how in the ctor the code show explicit addition of ColHeader objects
(not the default ColumnHeader which the designer will do if you use the
UI). Are you doing the same? Show us all the code...

Cheers
Daniel
--
http://www.danielmoth.com/Blog/


JamesL said:
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


Daniel Moth said:
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
 
Yep! That did it! Problem solved, works like a charm! Exactly what I
wanted to accomplish.

I can't thank you enough!

James Lysaght

JamesL said:
AH HA!!!! That's It!!!!

You hit it right there! I used the UI to add my column headers, I need to
add them in code so I get ColHeader objects instead...

I will experiment with that, I am sure that is the problem. It is obvious
to me now! Admittedly, I am feeling a little red in the face at the
moment. I should have caught that. Thanks a ton!

Sorry about forgetting to include the link to the quickstart:
irresponsible omission on my part. Thanks for looking it up!

James Lysaght

Daniel Moth said:
I found the quickstart you are talking about (you provided no link):
http://samples.gotdotnet.com/quicks...amework/samples/ListViewSort/ListViewSort.src

See how in the ctor the code show explicit addition of ColHeader objects
(not the default ColumnHeader which the designer will do if you use the
UI). Are you doing the same? Show us all the code...

Cheers
Daniel
--
http://www.danielmoth.com/Blog/


JamesL said:
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
 
Back
Top