■No34034に返信(ミンミンさんの記事)
> データバインドを行った場合でも、IComparerインターフェイスのように> かなり自由にソート方法を定義する方法はないでしょうか?
手抜き実装だとこんな感じ。
Imports System.ComponentModel
Public Class Form1
Private list As New SortableBindingList(Of Record)()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
list.Add(New Record(4, "あああ"))
list.Add(New Record(1, "いいい"))
list.Add(New Record(999, "これを先頭にする"))
list.Add(New Record(3, "ううう"))
list.Add(New Record(5, "えええ"))
list.Add(New Record(2, "あああ"))
DataGridView1.DataSource = list
End Sub
End Class
Public Class Record
Implements IComparable, IComparable(Of Record)
Public Property Id As Integer
Public Property Name As String
Public Sub New(id As Integer, name As String)
Me.Id = id
Me.Name = name
End Sub
Public Function CompareTo(other As Record) As Integer Implements IComparable(Of Record).CompareTo
'★ここが独自の比較処理★
If Id = 999 Then
Return -1
ElseIf other.Id = 999 Then
Return 1
Else
Return Id.CompareTo(other.Id)
End If
End Function
Private Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
Return Me.CompareTo(DirectCast(obj, Record))
End Function
End Class
Public Class SortableBindingList(Of T)
Inherits BindingList(Of T)
Protected Overrides ReadOnly Property SupportsSortingCore As Boolean
Get
Return True
End Get
End Property
Protected Overrides Sub ApplySortCore(prop As PropertyDescriptor, direction As ListSortDirection)
Dim list = TryCast(Items, List(Of T))
If list Is Nothing Then
Return
End If
list.Sort()
OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
End Sub
End Class
上記は、レコード側に IComparable を付けただけなので、
昇順/降順の切り替えや、別の列をソートするなどの対応が出来ません。
降順などにも対応させたい場合には、ApplySortCore の引数もチェックします。
また、その場合はレコード側に IComparable を実装するのではなく、
IComparer(Of T) を実装したカスタムソート用のクラスを用意して、
『list.Sort()』の代わりに『list.Sort( IComparer(Of T) )』を呼びだします。
参考リンク
https://garafu.blogspot.com/2016/09/cs-sorablebindinglist.html