2
\$\begingroup\$

This is my current method for populating the sub-items of ListView controls. I like this method for two reasons...

1) I don't have to keep up with the display order of the columns.

2) If I enable column re-ordering, I don't have to change anything with the code.

So, the question is... Is this a good approach? Can it be improved?

Note: I'm not too happy about declaring Result As Object. It seems like there should be a better way to handle that, but it's the only way I could get it to working.

Private Function RetrieveItem(Of T)(ByVal displayIndex As Integer) As T
 Dim Result As Object = If(GetType(T) Is GetType(ListViewItem), New ListViewItem, New ListViewItem.ListViewSubItem)
 Select Case displayIndex
 Case ColumnHeader1.DisplayIndex
 Result.Text = "First Item"
 Result.Tag = "First"
 Case (ColumnHeader2.DisplayIndex)
 Result.Text = "Second Column"
 Result.Tag = "Second"
 Case ColumnHeader3.DisplayIndex
 Result.Text = "Third Column"
 Result.Tag = "Third"
 Case ColumnHeader4.DisplayIndex
 Result.Text = "Fourth Column"
 Result.Tag = "Fourth"
 End Select
 Return Result
End Function

Example Usage...

Dim item As ListViewItem = RetrieveItem(Of ListViewItem)(0)
For i As Integer = 1 To ListView1.Columns.Count - 1
 item.SubItems.Add(RetrieveItem(Of ListViewItem.ListViewSubItem)(i))
Next
ListView1.Items.Add(item)

Here is the example I came up with using @MarkHurd's suggestion of using a Widening CType Operator...

Private Class LVI
 Public Name As String
 Public Text As String
 Public Tag As Object
 Public Sub New(ByVal name As String, ByVal text As String, ByVal tag As Object)
 Me.Name = name
 Me.Text = text
 Me.Tag = tag
 End Sub
 Public Shared Widening Operator CType(ByVal item As LVI) As ListViewItem
 Dim Result As New ListViewItem(item.Text)
 Result.Name = item.Name
 Result.Tag = item.Tag
 Return Result
 End Operator
 Public Shared Widening Operator CType(ByVal item As LVI) As ListViewItem.ListViewSubItem
 Dim Result As New ListViewItem.ListViewSubItem
 Result.Text = item.Text
 Result.Name = item.Name
 Result.Tag = item.Tag
 Return Result
 End Operator
End Class
Private Function RetrieveItem(ByVal index As Integer) As LVI
 Select Case index
 Case ColumnHeader1.DisplayIndex : Return New LVI("1", "First Column", "one")
 Case ColumnHeader2.DisplayIndex : Return New LVI("2", "Second Column", "two")
 Case ColumnHeader3.DisplayIndex : Return New LVI("3", "Third Column", "three")
 Case ColumnHeader4.DisplayIndex : Return New LVI("4", "Fourth Column", "four")
 Case Else : Return Nothing
 End Select
End Function

Example usage...

Dim item As ListViewItem = RetrieveItem(0)
For i As Integer = 1 To ListView1.Columns.Count - 1
 item.SubItems.Add(RetrieveItem(i))
Next
ListView1.Items.Add(item)

I like both of these approaches, but I feel like the first is shorter and easier to implement, so I lean towards the first option.

asked Jul 24, 2012 at 11:14
\$\endgroup\$
3
  • \$\begingroup\$ What's wrong with your expected problem of editing the font color? How is this not possible with your code (with obvious changes to actually try something, since your code does not seem to do anything with font color ATM)? \$\endgroup\$ Commented Jul 24, 2012 at 13:49
  • \$\begingroup\$ @Gaffi, In the original code you would have had to return a custom structure, or class, which I think would be tedious, or make a new function for each property. I have changed the code to use Generic Types instead which should overcome that problem. \$\endgroup\$ Commented Jul 24, 2012 at 15:09
  • \$\begingroup\$ "I'm not too happy about declaring Result As Object." That's not your fault: Microsoft should have at least defined an interface that both ListViewItem and ListViewSubItem implemented. \$\endgroup\$ Commented Jul 25, 2012 at 16:18

1 Answer 1

1
\$\begingroup\$

If you want to avoid the late bound .Text and .Tag you could just create your own private type, say LVI, containing these two properties and implicit Widening CType operators for ListViewItem and ListViewItem.ListViewSubItem. Then the Result As New LVI can be converted on return using Return CType(CTypeDynamic(Result, GetType(T)), T) in the latest VB.NET.

Without CTypeDynamic I don't have a working solution yet.

answered Jul 25, 2012 at 17:08
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I was previously unaware of Widening CType. Your suggestion looks promising... I think when I get a chance, I will experiment with that approach and see how it turns out. If I like it, I'll post it as an addendum to my question. \$\endgroup\$ Commented Jul 25, 2012 at 22:09

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.