I'm working on creating a simple example of using a TreeListView in VB.NET (or at least one I can follow), and I'm running into an issue. When I run the code below, everything initially works. I have a tree of pet owners with branches of pet names. But after I expand one of the nodes, and move my mouse, I get an error telling me I can't convert a string object to a petowner object (my object class). I understand what that means, but VS doesn't tell me where the error is, and I can't trap it in a try-catch either. I'm looking for some insights.
Also: can anyone tell me if my conversion from C# to VB is correct; specifically the lambda functions in place of the delegates in the ChildrenGetter and AspectGetter methods? I'm fairly certain that's where the error is.
Thanks in advance.
Public Class Form1
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim PetOwners As New List(Of PetOwner)
Dim PetOwner As PetOwner
PetOwner = New PetOwner
PetOwner.OwnerName = "Steve"
PetOwner.PetNames.Add("Bob the Cat")
PetOwner.PetNames.Add("Snoop the Dog")
PetOwners.Add(PetOwner)
PetOwner = New PetOwner
PetOwner.OwnerName = "Ann"
PetOwners.Add(PetOwner)
PetOwner = New PetOwner
PetOwner.OwnerName = "Joe"
PetOwner.PetNames.Add("Shoeless")
PetOwners.Add(PetOwner)
Try
tlvPetOwners.CanExpandGetter = Function(po As PetOwner) po.PetNames.Count > 0
tlvPetOwners.ChildrenGetter = Function(po As Object)
Dim RetVal As Object = Nothing
Try
If TypeOf po Is PetOwner Then
RetVal = CType(po, PetOwner).PetNames
Else
RetVal = po
End If
Catch ex As Exception
Debug.Print(ex.ToString)
Finally
End Try
Return RetVal
End Function
Dim OwnerColumn As New OLVColumn()
OwnerColumn.AspectGetter = Function(po As Object)
Dim RetVal As Object = Nothing
Try
If TypeOf po Is PetOwner Then
RetVal = CType(po, PetOwner).OwnerName
Else
RetVal = po
End If
Catch ex As Exception
Debug.Print(ex.ToString)
Finally
End Try
Return RetVal
End Function
tlvPetOwners.Columns.Add(OwnerColumn)
tlvPetOwners.Roots = PetOwners
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
End Class
Public Class PetOwner
Public OwnerName As String
Public PetNames As New List(Of String)
End Class
Okay, I figured it out, and learned a couple of things as well (yea me - lol). First off, I had come to the conclusion my problem existed from trying to use a list of strings as pet names, and had not created a list of custom objects called Pet with a property of Name to use as an AspectName for the TreeListView column like you would an ObjectListView. I didn't want to go through this much trouble to create a checklist of names in my actual project (this is just a test).
If you try something like this on an ObjectListView, you'll run into a problem with the AspectName method, and the same holds true for a TreeListView.
But, you can get around the problem by using a Lambda for the AspectGetter method, which essentially provides the pet name as the AspectName. Not useful in database applications, but useful if you're only trying to supply a checklist of names.
I then decided to use this approach for the TreeListView. I did have to create a second column to hold the pet name, and in doing so set the AspectGetter to this:
The trick is this line:
This allows you to define the string itself as the aspect name.
Here's my final code. It consists of both an ObjectListView (olvPets) and a TreeListView (tlvPetOwners) you'd have to place on a form. Anyway, I hope this helps someone else out.