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]())
または、に含まれるすべてのアイテム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"))