motorola

Dear all,

I googled and found the following implementations of BindingList that supports sorting/searching/filtering:

1. BindingListView created by Brian Noyes(author of "Data Binding with Windows Forms 2.0: Programming Smart Client Data Applications with .NET")

2. SearchableSortableBindingList created by Michael Weinhardt - http://msdn2.microsoft.com/en-us/library/ms993236.aspx

However, they don't support add, update, delete in filtered/sorted state. I am bad in programming and unfamiliar with .NET so I would like to know if there is one available on the web that supports this feature before I try to create one by myself.

Thank you very much.



Re: Windows Forms Data Controls and Databinding Supporting add, update, delete in filtered/sorted state in BindingList

Ken Tucker

Here is a VB one I have been working on

Code Snippet

Option Compare Text

Imports System.ComponentModel
Imports System.Reflection

Public Class BindingListView(Of T)
Inherits BindingList(Of T)
Implements IBindingListView

' Generic version of the Sortable Bindinglist on the got dot net website
' http://www.gotdotnet.com/Community/UserSamples/Details.aspx SampleGuid=661b91f1-03c5-487c-8732-59af89eba601
Private m_bIsSorted As Boolean = False
Private m_bIsFiltered As Boolean = False
Private m_SortDirection As ListSortDirection
Private m_SortProperty As PropertyDescriptor
Private m_strFilter As String
Private m_lstOrginal As New List(Of T)
Private filtering As Boolean = False

Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As T)
MyBase.InsertItem(index, item)
If Not filtering Then
m_lstOrginal.Insert(index, item)
End If
End Sub

Protected Overrides Sub RemoveItem(ByVal index As Integer)
MyBase.RemoveItem(index)
End Sub

Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As T)
Dim myItem As T = Items(index)
Dim intItem As Integer
MyBase.SetItem(index, item)
intItem = m_lstOrginal.IndexOf(myItem)
m_lstOrginal.Item(intItem) = myItem
End Sub

Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean
Get
Return True
End Get
End Property

Protected Overrides ReadOnly Property IsSortedCore() As Boolean
Get
Return m_bIsSorted
End Get
End Property

Protected Overrides Sub RemoveSortCore()
m_bIsSorted = False
End Sub

Protected Overrides Sub ApplySortCore(ByVal prop As System.ComponentModel.PropertyDescriptor, ByVal direction As System.ComponentModel.ListSortDirection)
' Get list to sort
Dim myitems As List(Of T) = TryCast(Me.Items, List(Of T))

' Apply and set the sort, if items to sort
If myitems IsNot Nothing Then

m_SortDirection = direction
m_SortProperty = prop


Dim pc As PropertyComparer(Of T) = _
New PropertyComparer(Of T)(prop, direction)

myitems.Sort(pc)
m_bIsSorted = True

Else
m_bIsSorted = False

End If

Me.OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))

End Sub

Protected Overrides ReadOnly Property SortPropertyCore() As System.ComponentModel.PropertyDescriptor
Get
Return m_SortProperty
End Get
End Property

Protected Overrides ReadOnly Property SortDirectionCore() As System.ComponentModel.ListSortDirection
Get
Return m_SortDirection
End Get
End Property

Public Sub ApplySort(ByVal sorts As System.ComponentModel.ListSortDescriptionCollection) Implements System.ComponentModel.IBindingListView.ApplySort

End Sub

Public Property Filter() As String Implements System.ComponentModel.IBindingListView.Filter
Get
Return m_strFilter
End Get
Set(ByVal value As String)
m_strFilter = value
If String.IsNullOrEmpty(value) Then
RemoveFilter()
Else
DoFilter()
End If
End Set
End Property

Public Sub RemoveFilter() Implements System.ComponentModel.IBindingListView.RemoveFilter
m_bIsFiltered = False
FillList(m_lstOrginal)
End Sub

Public ReadOnly Property SortDescriptions() As System.ComponentModel.ListSortDescriptionCollection Implements System.ComponentModel.IBindingListView.SortDescriptions
Get
Return Nothing
End Get
End Property

Public ReadOnly Property SupportsAdvancedSorting() As Boolean Implements System.ComponentModel.IBindingListView.SupportsAdvancedSorting
Get
Return False
End Get
End Property

Public ReadOnly Property SupportsFiltering() As Boolean Implements System.ComponentModel.IBindingListView.SupportsFiltering
Get
Return True
End Get
End Property

Private Sub FillList(ByVal lst As List(Of T))
filtering = True
For z As Integer = Items.Count - 1 To 0 Step -1
Items.RemoveAt(z)
Next
For Each i As T In lst
Items.Add(i)
Next
filtering = False
Me.OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
End Sub

Private Sub DoFilter()
FillList(DirectCast(Items, List(Of T)).FindAll(AddressOf FindFilter))
End Sub

Private Function FindFilter(ByVal value As T) As Boolean
Dim strSplit() As String = Filter.Split(" "c)
Dim pi As PropertyInfo = value.[GetType]().GetProperty(strSplit(0))
Dim Val As String = pi.GetValue(value, Nothing).ToString

Dim myType As Type = pi.PropertyType

If myType Is GetType(Integer) Or myType Is GetType(Short) Or myType Is GetType(Double) _
Or myType Is GetType(Single) Or myType Is GetType(Byte) Then
Return NumCompare(strSplit(1), CDbl(Val), CDbl(strSplit(2)))
Else
Return StringCompare(strSplit(1), Val, strSplit(2))
End If
End Function

Public Function NumCompare(ByVal strType As String, ByVal propval As Double, ByVal compareval As Double) As Boolean
Select Case strType
Case ">"
Return propval > compareval
Case "<"
Return propval < compareval
Case ">="
Return propval >= compareval
Case "<="
Return propval <= compareval
Case "<>"
Return propval <> compareval
Case Else
Return propval = compareval
End Select
End Function

Public Function StringCompare(ByVal strtype As String, ByVal propval As String, ByVal compareval As String) As Boolean
Select Case strtype
Case "="
Return propval = compareval
Case "like"
Try
Return propval Like compareval
Catch
Return propval = compareval
End Try
Case ">"
Return propval > compareval
Case "<"
Return propval < compareval
Case ">="
Return propval >= compareval
Case "<="
Return propval <= compareval
Case "<>"
Return propval <> compareval
Case Else
Return False
End Select
End Function
End Class

#Region "Using directives"
Imports System
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Reflection
#End Region

Public Class PropertyComparer(Of T)
Inherits System.Collections.Generic.Comparer(Of T)

' The following code contains code implemented by Rockford Lhotka:
' http://msdn.microsoft.com/library/default.asp url=/library/en-us/dnadvnet/html/vbnet01272004.asp

' The following code was then converted into VB from Michael Weinhardt's C# implementation at:
' http://msdn.microsoft.com/library/default.asp url=/library/en-us/dnforms/html/winforms02182005.asp

Private _property As PropertyDescriptor
Private _direction As ListSortDirection

Public Sub New(ByVal [property] As PropertyDescriptor, ByVal direction As ListSortDirection)
_property = [property]
_direction = direction
End Sub

#Region "IComparer<T>"
Public Overrides Function Compare(ByVal xWord As T, ByVal yWord As T) As Integer
' Get property values
Dim xValue As Object = GetPropertyValue(xWord, _property.Name)
Dim yValue As Object = GetPropertyValue(yWord, _property.Name)
' Determine sort order
If _direction = ListSortDirection.Ascending Then
Return CompareAscending(xValue, yValue)
Else
Return CompareDescending(xValue, yValue)
End If
End Function

Public Overloads Function Equals(ByVal xWord As T, ByVal yWord As T) As Boolean
Return xWord.Equals(yWord)
End Function
Public Overloads Function GetHashCode(ByVal obj As T) As Integer
Return obj.GetHashCode()
End Function
#End Region

' Compare two property values of any type
Private Function CompareAscending(ByVal xValue As Object, ByVal yValue As Object) As Integer
Dim result As Integer
' If values implement IComparer
If TypeOf xValue Is IComparable Then
result = (DirectCast(xValue, IComparable)).CompareTo(yValue)
Else
If xValue.Equals(yValue) Then
' If values don't implement IComparer but are equivalent
result = 0
Else
result = xValue.ToString().CompareTo(yValue.ToString())
End If
' Values don't implement IComparer and are not equivalent, so compare as string values
End If
' Return result
Return result
End Function
Private Function CompareDescending(ByVal xValue As Object, ByVal yValue As Object) As Integer
' Return result adjusted for ascending or descending sort order ie
' multiplied by 1 for ascending or -1 for descending
Return CompareAscending(xValue, yValue) * -1
End Function
Private Function GetPropertyValue(ByVal value As T, ByVal [property] As String) As Object
' Get property
Dim propertyInfo As PropertyInfo = value.[GetType]().GetProperty([property])
' Return value
Return propertyInfo.GetValue(value, Nothing)
End Function

End Class







Re: Windows Forms Data Controls and Databinding Supporting add, update, delete in filtered/sorted state in BindingList

motorola

Dear Ken Tucker,

Thank you very much. It works perfectly.