Skip to content

Instantly share code, notes, and snippets.

@tamago324
Created December 5, 2017 16:42
Show Gist options
  • Save tamago324/33df3e74efc6aedfda48e5329eea522d to your computer and use it in GitHub Desktop.
Save tamago324/33df3e74efc6aedfda48e5329eea522d to your computer and use it in GitHub Desktop.
SortableBindingListクラス(ソート可能なBndingList(Of T))。
' Form1には DataGridView1 が配置されているとする
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim textCol As New DataGridViewTextBoxColumn With {
.HeaderText = "名前",
.DataPropertyName = "Name"
}
DataGridView1.Columns.Add(textCol)
Dim text2Col As New DataGridViewTextBoxColumn With {
.HeaderText = "年齢",
.DataPropertyName = "Age"
}
DataGridView1.Columns.Add(text2Col)
Dim list As New SortableBindingList(Of Test)
list.Add(New Test("`山田 太郎", 29))
list.Add(New Test("`山田 花子", 20))
list.Add(New Test("`佐藤 次郎", 35))
list.Add(New Test("`金沢 拓也", 18))
DataGridView1.DataSource = list
End Sub
End Class
Public Class Test
Public Property Name As String
Public Property Age As Integer
Public Sub New(name As String, age As Integer)
Me.Name = name
Me.Age = age
End Sub
End Class
Imports System.ComponentModel
Imports System.Reflection
Public Class SortableBindingList(Of T)
Inherits BindingList(Of T)
Private _isSorted As Boolean
Private _sortDirection As ListSortDirection = ListSortDirection.Ascending
Private _sortProperty As PropertyDescriptor
Public Sub New()
End Sub
Public Sub New(ByVal list As IList(Of T))
MyBase.New(list)
End Sub
''' <summary>リストが並び替えられているかどうか</summary>
Protected Overrides ReadOnly Property IsSortedCore As Boolean
Get
Return _isSorted
End Get
End Property
''' <summary>並び替えをサポートするかどうか。永久にサポートするため、必ず、Trueを返す</summary>
Protected Overrides ReadOnly Property SupportsSortingCore As Boolean
Get
Return True
End Get
End Property
''' <summary>並び替えに関するのオブジェクトに定義されているプロパティ達?</summary>
Protected Overrides ReadOnly Property SortPropertyCore As PropertyDescriptor
Get
Return _sortProperty
End Get
End Property
''' <summary>並び替えの方向。ListDirectionのどちらかの値</summary>
Protected Overrides ReadOnly Property SortDirectionCore As ListSortDirection
Get
Return _sortDirection
End Get
End Property
Protected Overrides Sub ApplySortCore(
ByVal prop As PropertyDescriptor,
ByVal direction As ListSortDirection)
'ソートするためバインドされているリストを取得します。
Dim items As List(Of T) = TryCast(MyBase.Items, List(Of T))
'リストがあった場合、
'Comparerを生成してソート項目と項目名を渡します。
If (Not items Is Nothing) Then
Dim sc As New SampleComparer(Of T)(prop, direction)
items.Sort(sc)
'ソート済みに設定します。
Me._isSorted = True
Else
Me._isSorted = False
End If
'ソート結果、方向を保持しておきます。
Me._sortProperty = prop
Me._sortDirection = direction
'リストが変更(ソート)されたことをイベント通知します。
Me.OnListChanged(New ListChangedEventArgs(
ListChangedType.ItemMoved, prop))
End Sub
End Class
Public Class SampleComparer(Of T)
Implements IComparer(Of T)
Private _direction As ListSortDirection 'ソートの向き(昇順/降順)
Private _property As PropertyDescriptor 'ソート項目
Public Sub New(ByVal prop As PropertyDescriptor,
ByVal direction As ListSortDirection)
Me._property = prop
Me._direction = direction
End Sub
'同値の場合ゼロを返します。
Public Function Compare(ByVal objX As T, ByVal objY As T) _
As Integer Implements IComparer(Of T).Compare
' 比較対象のオブジェクトからクリックしたプロパティを取得します。
Dim valX As Object = Me.GetPropValue(objX, Me._property.Name)
Dim valY As Object = Me.GetPropValue(objY, Me._property.Name)
'directionの値(昇順/降順)に応じて取得した値を比較します。
If (Me._direction = ListSortDirection.Ascending) Then
Return Me.CompareAsc(valX, valY)
Else
Return Me.CompareDesc(valX, valY)
End If
End Function
'昇順で比較を行います。
Private Function CompareAsc(ByVal valX As Object,
ByVal valY As Object) As Integer
Return valX.ToString.CompareTo(valY.ToString)
End Function
'降順で比較を行います。
Private Function CompareDesc(ByVal valX As Object,
ByVal valY As Object) As Integer
Return (Me.CompareAsc(valX, valY) * -1)
End Function
'プロパティ値を取得します。
Private Function GetPropValue(ByVal val As T,
ByVal prop As String) As Object
Dim propInfo As PropertyInfo = val.GetType.GetProperty(prop)
Return propInfo.GetValue(val, Nothing)
End Function
End Class
https://codezine.jp/article/detail/1159?p=2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment