Torna al Thread

Namespace lemoncake.samples Imports System Imports System.Collections.Generic Imports System.Collections Imports System.Text Imports System.ComponentModel Public Class BindingListView Inherits BindingList Implements IBindingListView, IRaiseItemChangedEvents Private m_Sorted As Boolean = false Private m_Filtered As Boolean = false Private m_FilterString As String = Nothing Private m_SortDirection As ListSortDirection = ListSortDirection.Ascending Private m_SortProperty As PropertyDescriptor = Nothing Private m_SortDescriptions As ListSortDescriptionCollection = New ListSortDescriptionCollection Private m_OriginalCollection As List = New List Public Sub New() MyBase.New End Sub Public Sub New(ByVal list As List) MyBase.New(list) End Sub Protected Overrides ReadOnly Property SupportsSearchingCore As Boolean Get Return true End Get End Property Protected Overrides ReadOnly Property SupportsSortingCore As Boolean Get Return true End Get End Property Protected Overrides ReadOnly Property IsSortedCore As Boolean Get Return m_Sorted End Get End Property Protected Overrides ReadOnly Property SortDirectionCore As ListSortDirection Get Return m_SortDirection End Get End Property Protected Overrides ReadOnly Property SortPropertyCore As PropertyDescriptor Get Return m_SortProperty End Get End Property Property IBindingListView_Filter As String Implements IBindingListView.Filter Get Return m_FilterString End Get Set m_FilterString = value m_Filtered = true UpdateFilter End Set End Property ReadOnly Property IBindingListView_SortDescriptions As ListSortDescriptionCollection Implements IBindingListView.SortDescriptions Get Return m_SortDescriptions End Get End Property ReadOnly Property IBindingListView_SupportsAdvancedSorting As Boolean Implements IBindingListView.SupportsAdvancedSorting Get Return true End Get End Property ReadOnly Property IBindingListView_SupportsFiltering As Boolean Implements IBindingListView.SupportsFiltering Get Return true End Get End Property ReadOnly Property IBindingList_AllowNew As Boolean Implements IBindingList.AllowNew Get Return CheckReadOnly End Get End Property ReadOnly Property IBindingList_AllowRemove As Boolean Implements IBindingList.AllowRemove Get Return CheckReadOnly End Get End Property ReadOnly Property IRaiseItemChangedEvents_RaisesItemChangedEvents As Boolean Implements IRaiseItemChangedEvents.RaisesItemChangedEvents Get Return true End Get End Property Protected Overrides Function FindCore(ByVal property As PropertyDescriptor, ByVal key As Object) As Integer ' Simple iteration: Dim i As Integer = 0 Do While (i < Count) Dim item As T = Me(i) If property.GetValue(item).Equals(key) Then Return i End If i = (i + 1) Loop Return -1 ' Not found ' Alternative search implementation ' using List.FindIndex: 'Predicate<T> pred = delegate(T item) '{ ' if (property.GetValue(item).Equals(key)) ' return true; ' else ' return false; '}; 'List<T> list = Items as List<T>; 'if (list == null) ' return -1; 'return list.FindIndex(pred); End Function Protected Overrides Sub ApplySortCore(ByVal property As PropertyDescriptor, ByVal direction As ListSortDirection) m_SortDirection = direction m_SortProperty = property Dim comparer As SortComparer = New SortComparer(property, direction) ApplySortInternal(comparer) End Sub Private Sub ApplySortInternal(ByVal comparer As SortComparer) If (m_OriginalCollection.Count = 0) Then m_OriginalCollection.AddRange(Me) End If Dim listRef As List = CType(Me.Items,List) If (listRef Is Nothing) Then Return End If listRef.Sort(comparer) m_Sorted = true OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1)) End Sub Protected Overrides Sub RemoveSortCore() If Not m_Sorted Then Return End If Clear For Each item As T In m_OriginalCollection Add(item) Next m_OriginalCollection.Clear m_SortProperty = Nothing m_SortDescriptions = Nothing m_Sorted = false End Sub Sub IBindingListView_ApplySort(ByVal sorts As ListSortDescriptionCollection) Implements IBindingListView.ApplySort m_SortProperty = Nothing m_SortDescriptions = sorts Dim comparer As SortComparer = New SortComparer(sorts) ApplySortInternal(comparer) End Sub Sub IBindingListView_RemoveFilter() Implements IBindingListView.RemoveFilter If Not m_Filtered Then Return End If m_FilterString = Nothing m_Filtered = false m_Sorted = false m_SortDescriptions = Nothing m_SortProperty = Nothing Clear For Each item As T In m_OriginalCollection Add(item) Next m_OriginalCollection.Clear End Sub Protected Overridable Sub UpdateFilter() Dim equalsPos As Integer = m_FilterString.IndexOf(Microsoft.VisualBasic.ChrW(61)) ' Get property name Dim propName As String = m_FilterString.Substring(0, equalsPos).Trim ' Get filter criteria Dim criteria As String = m_FilterString.Substring((equalsPos + 1), (m_FilterString.Length _ - (equalsPos - 1))).Trim ' Strip leading and trailing quotes criteria = criteria.Substring(1, (criteria.Length - 2)) ' Get a property descriptor for the filter property Dim propDesc As PropertyDescriptor = TypeDescriptor.GetProperties(GetType(T))(propName) If (m_OriginalCollection.Count = 0) Then m_OriginalCollection.AddRange(Me) End If Dim currentCollection As List = New List(Me) Clear For Each item As T In currentCollection Dim value As Object = propDesc.GetValue(item) ' strip newline characters as it was causing issues with contains Dim sval As String = value.ToString.Replace(""& vbLf, "").Replace(""& vbCr, "") If sval.ToString.Contains(criteria) Then Add(item) End If Next End Sub Private Function CheckReadOnly() As Boolean If (m_Sorted OrElse m_Filtered) Then Return false Else Return true End If End Function Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As T) For Each propDesc As PropertyDescriptor In TypeDescriptor.GetProperties(item) If propDesc.SupportsChangeEvents Then propDesc.AddValueChanged(item, OnItemChanged) End If Next MyBase.InsertItem(index, item) End Sub Protected Overrides Sub RemoveItem(ByVal index As Integer) Dim item As T = Items(index) Dim propDescs As PropertyDescriptorCollection = TypeDescriptor.GetProperties(item) For Each propDesc As PropertyDescriptor In propDescs If propDesc.SupportsChangeEvents Then propDesc.RemoveValueChanged(item, OnItemChanged) End If Next MyBase.RemoveItem(index) End Sub Private Sub OnItemChanged(ByVal sender As Object, ByVal args As EventArgs) Dim index As Integer = Items.IndexOf(CType(sender,T)) OnListChanged(New ListChangedEventArgs(ListChangedType.ItemChanged, index)) End Sub End Class Class SortComparer Inherits IComparer Private m_SortCollection As ListSortDescriptionCollection = Nothing Private m_PropDesc As PropertyDescriptor = Nothing Private m_Direction As ListSortDirection = ListSortDirection.Ascending Public Sub New(ByVal propDesc As PropertyDescriptor, ByVal direction As ListSortDirection) MyBase.New m_PropDesc = propDesc m_Direction = direction End Sub Public Sub New(ByVal sortCollection As ListSortDescriptionCollection) MyBase.New m_SortCollection = sortCollection End Sub Function IComparer_Compare(ByVal x As T, ByVal y As T) As Integer Implements IComparer.Compare If (Not (m_PropDesc) Is Nothing) Then Dim xValue As Object = m_PropDesc.GetValue(x) Dim yValue As Object = m_PropDesc.GetValue(y) Return CompareValues(xValue, yValue, m_Direction) ElseIf ((Not (m_SortCollection) Is Nothing) _ AndAlso (m_SortCollection.Count > 0)) Then Return RecursiveCompareInternal(x, y, 0) Else Return 0 End If End Function Private Function CompareValues(ByVal xValue As Object, ByVal yValue As Object, ByVal direction As ListSortDirection) As Integer Dim retValue As Integer = 0 If (TypeOf xValue Is IComparable) Then retValue = CType(xValue,IComparable).CompareTo(yValue) ElseIf (TypeOf yValue Is IComparable) Then retValue = CType(yValue,IComparable).CompareTo(xValue) End If ' not comparable, compare String representations If Not xValue.Equals(yValue) Then retValue = xValue.ToString.CompareTo(yValue.ToString) End If If (direction = ListSortDirection.Ascending) Then Return retValue Else Return (retValue * -1) End If End Function Private Function RecursiveCompareInternal(ByVal x As T, ByVal y As T, ByVal index As Integer) As Integer If (index >= m_SortCollection.Count) Then Return 0 End If ' termination condition Dim listSortDesc As ListSortDescription = m_SortCollection(index) Dim xValue As Object = listSortDesc.PropertyDescriptor.GetValue(x) Dim yValue As Object = listSortDesc.PropertyDescriptor.GetValue(y) Dim retValue As Integer = CompareValues(xValue, yValue, listSortDesc.SortDirection) If (retValue = 0) Then Return RecursiveCompareInternal(x, y, ++, index) Else Return retValue End If End Function End Class End Namespace
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5