假设预定义的类是例如模型示例song,来自OLV 站点:
Public Class Song
Public Sub New()
Me.New(String.Empty, DateTime.Now, 0)
End Sub
Public Sub New(title As String, lastPlayed As DateTime, rating As Integer)
Me.Title = title
Me.LastPlayed = lastPlayed
Me.Rating = rating
End Sub
Public Property Title() As String
Public Property LastPlayed() As DateTime
Public Property Rating() As Integer
Public Function GetSizeInMb() As Single
Return 1.2
End Function
End Class
以下假设ListViewItem已填充:
请注意,OLV 方法SetObjects接受一个IEnumerable对象,因此我们将返回一个List(T)对象。(与 OP 中链接的“Get”方法相同。)现在,将这些扩展方法添加到Module.
Public Module MyExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Function ToSong(item As ListViewItem) As Song
Dim title As String = item.SubItems(0).Text
'Dim GetSizeInMb() As Single = Single.Parse(item.SubItems(1).Text) < -Skip, It 's a function in this example.
Dim lastPlayed = DateTime.Parse(item.SubItems(2).Text)
Dim rating = Integer.Parse(item.SubItems(3).Text)
Return New Song(title, lastPlayed, rating)
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](view As ListView) As List(Of Song)
Dim list As New List(Of Song)
For Each item As ListViewItem In view.Items
list.Add(item.ToSong())
Next
Return list
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](collection As IEnumerable(Of ListViewItem)) As List(Of Song)
Dim list As New List(Of Song)
For Each item As ListViewItem In collection
list.Add(item.ToSong())
Next
Return list
End Function
End Module
用法:
单人ListViewItem:
Dim item As ListViewItem = 'Some listviewitem
Me.olvSongs.SetObjects({item.ToSong()})
多个ListViewItem:
Dim item1 As ListViewItem = 'Some listviewitem
Dim item2 As ListViewItem = 'Some listviewitem
Dim item3 As ListViewItem = 'Some listviewitem
Me.olvSongs.SetObjects({item1, item2, item3}.[Get]())
或包含在 a 中的所有项目ListView:
Dim view As ListView = 'Some listview
Me.olvSongs.SetObjects(view.[Get]())
选项 2 - “接口方式”
下一个选项更具动态性。通过在您的预定义类中实现接口IMergable(T),所有人都将支持该Get方法。
Public Interface IMergable(Of T)
Sub Merge(item As T)
End Interface
Public Module MyExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](Of T)(item As ListViewItem) As List(Of T)
Dim list As New List(Of T)
Dim obj As T = Activator.CreateInstance(Of T)()
If (GetType(T).IsAssignableFrom(GetType(IMergable(Of ListViewItem)))) Then
DirectCast(obj, IMergable(Of ListViewItem)).Merge(item)
list.Add(obj)
End If
Return list
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](Of T)(view As ListView) As List(Of T)
Dim list As New List(Of T)
If (GetType(T).IsAssignableFrom(GetType(IMergable(Of ListViewItem)))) Then
Dim obj As T = Nothing
For Each item As ListViewItem In view.Items
obj = Activator.CreateInstance(Of T)()
DirectCast(obj, IMergable(Of ListViewItem)).Merge(item)
list.Add(obj)
Next
End If
Return list
End Function
End Module
执行:
Public Class Song
Implements IMergable(Of ListViewItem)
...
Private Sub Merge(item As ListViewItem) Implements IMergable(Of ListViewItem).Merge
If (item Is Nothing) Then
Throw New ArgumentNullException("item")
End If
Me.Title = item.SubItems(0).Text
'Me.GetSizeInMb = Single.Parse(item.SubItems(1).Text) < -Skip, It 's a function in this example.
Me.LastPlayed = DateTime.Parse(item.SubItems(2).Text)
Me.Rating = Integer.Parse(item.SubItems(3).Text)
End Sub
End Class
用法:
Me.olvSongs.SetObjects(myListView.[Get](Of Song)())
Me.olvSongs.SetObjects(myListViewItem.[Get](Of Song)())
Me.olvSongs.SetObjects(myListView.[Get](Of PreDefClassType1)())
Me.olvSongs.SetObjects(myListView.[Get](Of PreDefClassType2)())
选项 3 - “反思方式”
此示例仅支持IConvertible数据类型。
Public Module MyExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](Of T)(view As ListView, ParamArray members As String()) As List(Of T)
Dim list As New List(Of ListViewItem)
For Each item As ListViewItem In view.Items
list.Add(item)
Next
Return list.Get(Of T)(members)
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](Of T)(item As ListViewItem, ParamArray members As String()) As List(Of T)
Return New ListViewItem() {item}.Get(Of T)(members)
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function [Get](Of T)(collection As IEnumerable(Of ListViewItem), ParamArray members As String()) As List(Of T)
Dim list As New List(Of T)
Dim length As Integer = (members.Length - 1)
If (length > -1) Then
Dim type As Type = GetType(T)
Dim info As KeyValuePair(Of MemberInfo, Type)() = New KeyValuePair(Of MemberInfo, Type)(length) {}
For index As Integer = 0 To length
For Each m As MemberInfo In type.GetMember(members(index), (MemberTypes.Method Or MemberTypes.Property), (BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly))
If (m.MemberType = MemberTypes.Property) Then
With DirectCast(m, PropertyInfo)
If (.CanWrite AndAlso (.GetIndexParameters().Length = 0)) Then
info(index) = New KeyValuePair(Of MemberInfo, Type)(m, .PropertyType)
Exit For
End If
End With
ElseIf (m.MemberType = MemberTypes.Method) Then
With DirectCast(m, MethodInfo)
Dim params As ParameterInfo() = .GetParameters()
If (params.Length = 1) Then
info(index) = New KeyValuePair(Of MemberInfo, Type)(m, params(0).ParameterType)
Exit For
End If
End With
End If
Next
Next
For Each item As ListViewItem In collection
Dim obj As T = Activator.CreateInstance(Of T)()
Dim ict As Type = GetType(IConvertible)
For index As Integer = 0 To length
Dim pair As KeyValuePair(Of MemberInfo, Type) = info(index)
If (Not pair.Key Is Nothing) Then
If (ict.IsAssignableFrom(pair.Value)) Then
If (pair.Key.MemberType = MemberTypes.Property) Then
DirectCast(pair.Key, PropertyInfo).SetValue(obj, System.Convert.ChangeType(item.SubItems(index).Text, pair.Value), Nothing)
Else
DirectCast(pair.Key, MethodInfo).Invoke(obj, System.Convert.ChangeType(item.SubItems(index).Text, pair.Value))
End If
Else
'TODO: Support other data types.
'If (pair.Key.MemberType = MemberTypes.Property) Then
'DirectCast(pair.Key, PropertyInfo).SetValue(obj, item.SubItems(index).Text, Nothing)
'Else
'DirectCast(pair.Key, MethodInfo).Invoke(obj, New Object() {item.SubItems(index).Text})
'End If
End If
End If
Next
list.Add(obj)
Next
End If
Return list
End Function
End Module
用法:
Me.olvSongs.SetObjects(myListView.[Get](Of Song)("Title", "GetSizeInMb", "LastPlayed", "Rating"))
Me.olvSongs.SetObjects(myListViewItem.[Get](Of Song)("Title", "GetSizeInMb", "LastPlayed", "Rating"))
Me.olvSongs.SetObjects(myListView.[Get](Of PreDefClassType1)("Prop1", "Prop2", "Prop3"))
Me.olvSongs.SetObjects(myListView.[Get](Of PreDefClassType2)("PropA", "PropB", "PropC"))