|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Sorting a System.Collections.ObjectModel.CollectionHow do you sort a generic collection derived from
System.Collections.ObjectModel.Collection? Thanks in advance, - Arthur Dent Hi,
I made this Generic 'base' List that I use to store collections of objects. It allows me to sort them, show them in a datagrid/datagridview, search on propertys, and some stuff to save all the items in the class, see if they have changes etc. Just pick out the things you need :-) I hope this helps. Pieter Option Explicit On Imports System.Windows.Forms Imports System.ComponentModel Imports System.Collections Imports System.Collections.Specialized Public Class clsBaseList(Of T As clsBaseClass) Inherits BindingList(Of T) Implements IComponent Public Sub New() MyBase.New() Me.AllowNew = False Me.AllowRemove = True End Sub #Region "IComponent Implementation" Private m_Site As ISite = Nothing Public Event Disposed(ByVal sender As Object, ByVal e As System.EventArgs) _ Implements System.ComponentModel.IComponent.Disposed Protected Property Site() As System.ComponentModel.ISite Implements _ System.ComponentModel.IComponent.Site Get Return m_Site End Get Set(ByVal Value As System.ComponentModel.ISite) m_Site = Value End Set End Property Public Sub Dispose() Implements System.IDisposable.Dispose Me.Items.Clear() RaiseEvent Disposed(Me, System.EventArgs.Empty) End Sub #End Region #Region "IBindingList Sorting Features" Private m_SupportsSorting As Boolean = True Private m_SortProperty As PropertyDescriptor Private m_SortDirection As ListSortDirection Private m_OriginalList As ArrayList Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean Get Return m_SupportsSorting End Get End Property Protected Overrides ReadOnly Property SortDirectionCore() As System.ComponentModel.ListSortDirection Get Return m_SortDirection End Get End Property Protected Overrides ReadOnly Property SortPropertyCore() As System.ComponentModel.PropertyDescriptor Get Return m_SortProperty End Get End Property Protected Overrides ReadOnly Property IsSortedCore() As Boolean Get Return m_SortProperty Is Nothing End Get End Property Private Sub SaveList() m_OriginalList = New ArrayList(Me.Items) End Sub Private Sub ResetList(ByVal NewList As ArrayList) Me.ClearItems() For Each m_T As T In NewList Me.Add(m_T) Next End Sub Private Sub DoSort() Dim m_Comparer As New clsListComparer(m_SortProperty, m_SortDirection) Dim m_SortList As New ArrayList(Me.Items) m_SortList.Sort(m_Comparer) ResetList(m_SortList) End Sub Protected Overrides Sub ApplySortCore(ByVal prop As System.ComponentModel.PropertyDescriptor, ByVal direction As System.ComponentModel.ListSortDirection) 'toegevoegd door Pieter want sorteerde enkel Ascending in een DataGridView... If m_SortProperty IsNot Nothing Then If (m_SortProperty.Name = prop.Name) And (m_SortDirection = direction) Then 'wisselen! direction = (direction + 1) Mod 2 End If End If m_SortProperty = prop m_SortDirection = direction If (m_OriginalList Is Nothing) Then SaveList() End If DoSort() End Sub Protected Overrides Sub RemoveSortCore() ResetList(m_OriginalList) m_SortDirection = Nothing m_SortProperty = Nothing End Sub #End Region #Region "Private Variabel Declarations" Private m_blnSavedSuccesfull As Boolean Private m_blnDeletedSuccesfull As Boolean Private m_blnCatchChanges As Boolean = True Private m_blnHasChanges As Boolean = False Private m_strEntiteName As String = "entité" Private m_strEntiteCe As String = "cette" Private m_blnSelected As Boolean = True Private m_blnFilling As Boolean = False Private m_blnThrowEveryChangesEvent As Boolean = False #End Region #Region "Protected Variabel Declarations" #End Region #Region "Protected Methods" ''' <name>Sub SaveBegin</name> ''' <summary> ''' Method to call at the beginning of a Save. ''' </summary> ''' <history> ''' PCO Created ''' </history> Protected Sub SaveBegin() Me.SavedSuccesfull = True End Sub ''' <name>Sub SaveEnd</name> ''' <summary> ''' Method to call at the end of a Save. Calls SetClassToUnchangedState(). Must only be called on SavedSuccesfull. ''' </summary> ''' <history> ''' PCO Created ''' </history> Protected Sub SaveEnd() If Me.SavedSuccesfull Then 'Après qu'on a sauvegarder tout les info: donne la message qu'on a tout bien sauvegarder et qu'on peut remttre le control dans un état "pas de changements" SetCollectionToUnchangedState() Else 'tell the user that his class wasn't saved succesfully! End If 'raise the event that the save has ended 'RaiseEvent SaveHasEnded(Me, EventArgs.Empty) End Sub ''' <name>Sub DeleteBegin</name> ''' <summary> ''' Method to call at the beginning of a Delete. ''' </summary> ''' <history> ''' PCO Created ''' </history> Protected Sub DeleteBegin() Me.DeletedSuccesfull = True End Sub #End Region #Region "Public Propertys" ''' <name>Property SavedSuccesfull</name> ''' <returns>Boolean</returns> ''' <summary> ''' Indique si la classe a été sauvegarder avec succès. ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property SavedSuccesfull() As Boolean Get Return m_blnSavedSuccesfull End Get Set(ByVal value As Boolean) m_blnSavedSuccesfull = value End Set End Property ''' <name>Property DeletedSuccesfull</name> ''' <returns>Boolean</returns> ''' <summary> ''' Indique si la classe a été supprimé avec succès. ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property DeletedSuccesfull() As Boolean Get Return m_blnDeletedSuccesfull End Get Set(ByVal value As Boolean) m_blnDeletedSuccesfull = value End Set End Property ''' <name>Property CatchChanges</name> ''' <returns>Boolean</returns> ''' <summary> ''' Indique si le control doit réagir sur des changements ou pas: par exemple pas pendant qu'on fait le load d'une entité... ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property CatchChanges() As Boolean Get Return m_blnCatchChanges End Get Set(ByVal value As Boolean) m_blnCatchChanges = value Dim clsI As clsBaseClass For Each clsI In MyBase.Items clsI.CatchChanges = m_blnCatchChanges Next End Set End Property ''' <name>Property ThrowEveryChangesEvent</name> ''' <returns>Boolean</returns> ''' <summary> ''' Indique qu'un evenement doit être raised à chaque changement, ou seulement le premier fois... ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property ThrowEveryChangesEvent() As Boolean Get Return m_blnThrowEveryChangesEvent End Get Set(ByVal value As Boolean) m_blnThrowEveryChangesEvent = value End Set End Property '<System.ComponentModel.DefaultValue(False)> _ Public Event HasChangesEvent As EventHandler(Of HasChangesEventArgs) ''' <name>Property HasChanges</name> ''' <returns>Boolean</returns> ''' <summary> ''' True s'il y a des changements qui se sont passés aux propertys de la classe. ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property HasChanges() As Boolean Get Return m_blnHasChanges End Get Set(ByVal value As Boolean) m_blnHasChanges = value End Set End Property ''' <name>Property EntiteName</name> ''' <returns>String</returns> ''' <summary> ''' Le nom de l'entité de la classe. ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property EntiteName() As String Get Return m_strEntiteName End Get Set(ByVal value As String) m_strEntiteName = value End Set End Property ''' <name>Property EntiteCe</name> ''' <returns>String</returns> ''' <summary> ''' CET adresse, CE fournisseur, ... ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Property EntiteCe() As String Get Return m_strEntiteCe End Get Set(ByVal value As String) m_strEntiteCe = value End Set End Property #End Region #Region "Base Collection Methods" ''' <name>Function TestCloseCollection</name> ''' <returns>Integer</returns> ''' <summary> ''' This Methode tests for unsaved changes when CatchChanges is True, and ask to save unchanged changes. ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Function TestCloseCollection() As Integer If Me.m_blnCatchChanges And Me.m_blnHasChanges Then Dim intA As Integer intA = MessageBox.Show("Vous avez fait des changements depuis le dernier sauvegarde." & vbCrLf & "Est-ce que vous voulez les sauvegarder?", "Sauvegarder changements?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) If intA = vbYes Then 'raise event to save the changes 'RaiseEvent Click_Save() If Me.Save() Then 'if succesfully saved: class can be disposed/finalized... Return vbYes Else 'if not: don't close it... Return vbCancel End If ElseIf intA = vbNo Then 'if they don't want to save the changes: disable the changes-handler Me.CatchChanges = False Return intA Else Return intA End If Else Return vbYes End If End Function ''' <name>Function Save</name> ''' <returns>Boolean</returns> ''' <summary> ''' ' Update les changements ou insert les dans la base de données pour tout les objets dans la collection. ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Function Save() As Boolean Try Me.SaveBegin() Dim clsI As clsBaseClass For Each clsI In MyBase.Items If Not clsI.Save() Then SavedSuccesfull = False Next Catch ex As Exception 'ErrorMessage(ex) SavedSuccesfull = False Throw ex End Try Me.SaveEnd() Return SavedSuccesfull End Function ''' <name>Function Delete</name> ''' <returns>Boolean</returns> ''' <summary> ''' Supprime tout les éléments dans la liste ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Function Delete() As Boolean Try Me.DeleteBegin() Dim clsI As clsBaseClass For Each clsI In MyBase.Items If Not clsI.Delete Then Me.DeletedSuccesfull = False Return Me.DeletedSuccesfull Exit Function End If Next 'remove them all Me.Clear() Catch ex As Exception 'ErrorMessage(ex) Me.DeletedSuccesfull = False Throw ex End Try Return Me.DeletedSuccesfull End Function ''' <name>Function Delete</name> ''' <returns>Boolean</returns> ''' <summary> ''' Deletes a specified Object in the List ''' </summary> ''' <param name="item">ByVal item As T: The item that must be deleted</param> ''' <history> ''' PCO Created ''' </history> Public Function Delete(ByVal item As T) As Boolean Try Me.DeleteBegin() If Not item.Delete Then Me.DeletedSuccesfull = False Me.Remove(item) Catch ex As Exception 'ErrorMessage(ex) Me.DeletedSuccesfull = False Throw ex End Try Return Me.DeletedSuccesfull End Function ''' <name>Sub SetCollectionToUnchangedState</name> ''' <summary> ''' Methode qui remets le HasChanges = False et CatchChanges = True ''' </summary> ''' <history> ''' PCO Created ''' </history> Public Sub SetCollectionToUnchangedState() 'reset it CatchChanges = True HasChanges = False End Sub Private Sub OnObjectInListChangedHandler(ByVal sender As Object, ByVal e As HasChangesEventArgs) 'always... ''regarde si on n'as pas déjà fait... ''If (Not m_blnHasChanges) Then 'il y a une valeur qui est changé! ''ok, il y a une valeur changé HasChanges = True RaiseEvent HasChangesEvent(sender, e) ''End If End Sub Private Sub OnObjectInListSelectedChangedHandler(ByVal sender As Object, ByVal e As HasChangesEventArgs) 'always... RaiseEvent HasChangesSelectedEvent(sender, e) End Sub Public Event HasChangesSelectedEvent As EventHandler(Of HasChangesEventArgs) ''' <name>ReadOnly Property SelectedCount()</name> ''' <returns>Integer</returns> ''' <summary> ''' Property qui retourne le nombre d'Items dans la collection qui a le property Selected = True ''' </summary> ''' <history> ''' PCO Created ''' </history> Public ReadOnly Property SelectedCount() As Integer Get Dim clsB As clsBaseClass Dim intC As Integer = 0 For Each clsB In MyBase.Items If clsB.Selected Then intC += 1 End If Next Return intC End Get End Property #End Region #Region "List Methods" Public Shadows Sub Add(ByVal item As T) item.SetClassToUnchangedState() AddHandler item.HasChangesEvent, AddressOf OnObjectInListChangedHandler AddHandler item.SelectedChanged, AddressOf OnObjectInListSelectedChangedHandler MyBase.Add(item) End Sub Public Shadows Sub Insert(ByVal index As Integer, ByVal item As T) item.SetClassToUnchangedState() AddHandler item.HasChangesEvent, AddressOf OnObjectInListChangedHandler AddHandler item.SelectedChanged, AddressOf OnObjectInListSelectedChangedHandler MyBase.Insert(index, item) End Sub Public Shadows Sub Clear() For Each item As clsBaseClass In Me RemoveHandler item.HasChangesEvent, AddressOf OnObjectInListChangedHandler RemoveHandler item.SelectedChanged, AddressOf OnObjectInListSelectedChangedHandler Next MyBase.Clear() End Sub Public Shadows Function Remove(ByVal item As T) As Boolean RemoveHandler item.HasChangesEvent, AddressOf OnObjectInListChangedHandler RemoveHandler item.SelectedChanged, AddressOf OnObjectInListSelectedChangedHandler Return MyBase.Remove(item) End Function Public Shadows Sub RemoveAt(ByVal index As Integer) RemoveHandler MyBase.Item(index).HasChangesEvent, AddressOf OnObjectInListChangedHandler RemoveHandler MyBase.Item(index).SelectedChanged, AddressOf OnObjectInListSelectedChangedHandler MyBase.RemoveAt(index) End Sub 'very important, otherwise it will return objects of clsBaseClass, and not object of T... Default Public Shadows Property Item(ByVal index As Integer) As T Get Return MyBase.Item(index) End Get Set(ByVal value As T) AddHandler value.HasChangesEvent, AddressOf OnObjectInListChangedHandler AddHandler value.SelectedChanged, AddressOf OnObjectInListSelectedChangedHandler MyBase.Item(index) = value End Set End Property #End Region #Region "Searching" Protected Overrides ReadOnly Property SupportsSearchingCore() As Boolean Get Return True End Get End Property ' Item property descriptor collection cache Dim pdc As PropertyDescriptorCollection = Nothing Protected Overrides Function FindCore(ByVal [property] As PropertyDescriptor, ByVal key As Object) As Integer ' Specify search columns If ([property] Is Nothing) Then Return -1 End If ' Get list to search Dim items As List(Of T) = Me.Items ' Traverse list for value For Each item As T In items ' Test column search value Dim value As String = CStr([property].GetValue(item)) 'If value is the search value, return the ' index of the data item If (CStr(key) = value) Then Return IndexOf(item) End If Next item Return -1 End Function 'ByVal [property] As PropertyDescriptor, ByVal key As Object Public Function FindItems(ByVal ColumnName As String, ByVal ColumnValue As Object) As clsBaseList(Of T) Dim lst As New clsBaseList(Of T) Dim properties As PropertyDescriptorCollection Dim myProperty As PropertyDescriptor ' Specify search columns If (ColumnName Is Nothing) Then Return Nothing End If ' Get list to search Dim items As List(Of T) = Me.Items ' Traverse list for value For Each item As T In items properties = TypeDescriptor.GetProperties(item.GetType) myProperty = properties.Find(ColumnName, False) ' Test column search value Dim value As String = CStr(myProperty.GetValue(item)) 'If value is the search value, return the ' index of the data item If (CStr(ColumnValue) = value) Then lst.Add(item) End If Next item Return lst End Function Public Function FindItem(ByVal ColumnName As String, ByVal ColumnValue As Object) As T Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(Me.Items(0).GetType) Dim myProperty As PropertyDescriptor = properties.Find(ColumnName, False) Dim i As Integer = FindCore(myProperty, ColumnValue) If i = -1 Then Return Nothing Else Return Me.Item(i) End If End Function Public Function SumItems(ByVal ColumnName As String) As Decimal Dim properties As PropertyDescriptorCollection Dim myProperty As PropertyDescriptor ' Specify search columns If (ColumnName Is Nothing) Then Return Nothing End If ' Get list to search Dim items As List(Of T) = Me.Items ' Traverse list for value Dim decSum As Decimal = 0 For Each item As T In items properties = TypeDescriptor.GetProperties(item.GetType) myProperty = properties.Find(ColumnName, False) 'Dim value As String = CStr(myProperty.GetValue(item)) decSum += CSng(myProperty.GetValue(item)) Next item Return decSum End Function #End Region End Class Public Class clsListComparer Implements IComparer Private m_SortList As ListSortDescriptionCollection Public Sub New(ByVal SortProperty As PropertyDescriptor, ByVal direction As ListSortDirection) 'Create a new list every time m_SortList = New ListSortDescriptionCollection(New ListSortDescription() {New ListSortDescription(SortProperty, direction)}) End Sub Public Sub New(ByVal SortList As ListSortDescriptionCollection) m_SortList = SortList End Sub Private Function CompareSingleProperty(ByVal x As clsBaseClass, ByVal y As clsBaseClass, ByVal prop As PropertyDescriptor, ByVal direction As ListSortDirection) As Integer Dim result As Integer = 0 Dim directionModifier As Integer If (direction = ListSortDirection.Ascending) Then directionModifier = 1 Else directionModifier = -1 End If If (x Is Nothing) Then result = -1 * directionModifier ElseIf (y Is Nothing) Then result = 1 * directionModifier ElseIf (prop.GetValue(x) < prop.GetValue(y)) Then result = -1 * directionModifier ElseIf (prop.GetValue(x) > prop.GetValue(y)) Then result = 1 * directionModifier Else result = 0 End If Return result End Function Private Function Compare(ByVal x As Object, ByVal y As Object) As Integer _ Implements System.Collections.IComparer.Compare Dim idx As Integer Dim result As Integer If (Not TypeOf x Is clsBaseClass) Then Throw New ArgumentException("Unexpected Argument. Arguments must be of Type ", "x") End If If (Not TypeOf y Is clsBaseClass) Then Throw New ArgumentException("Unexpected Argument. Arguments must be of Type ", "y") End If For idx = 0 To m_SortList.Count - 1 result = CompareSingleProperty(x, y, m_SortList(idx).PropertyDescriptor, m_SortList(idx).SortDirection) If (result <> 0) Then Exit For End If Next Return result End Function End Class I could do that, but the thing is that that defeats the point of OO. I was
trying to take advantage of the generic collection as a base so i wouldnt have to reinvent the wheel..... theres a lot of code involved in coding collection classes. Show quoteHide quote "Pieter" <pietercou***@hotmail.com> wrote in message news:OxBdGEZTGHA.4960@TK2MSFTNGP12.phx.gbl... > Hi, > > I made this Generic 'base' List that I use to store collections of > objects. It allows me to sort them, show them in a datagrid/datagridview, > search on propertys, and some stuff to save all the items in the class, > see if they have changes etc. Just pick out the things you need :-) > > I hope this helps. > > Pieter > > Option Explicit On > > Imports System.Windows.Forms > > Imports System.ComponentModel > Imports System.Collections > Imports System.Collections.Specialized > > Public Class clsBaseList(Of T As clsBaseClass) > Inherits BindingList(Of T) > Implements IComponent > > Public Sub New() > MyBase.New() > Me.AllowNew = False > Me.AllowRemove = True > End Sub > > #Region "IComponent Implementation" > Private m_Site As ISite = Nothing > Public Event Disposed(ByVal sender As Object, ByVal e As > System.EventArgs) _ > Implements System.ComponentModel.IComponent.Disposed > > Protected Property Site() As System.ComponentModel.ISite Implements _ > System.ComponentModel.IComponent.Site > Get > Return m_Site > End Get > Set(ByVal Value As System.ComponentModel.ISite) > m_Site = Value > End Set > End Property > > Public Sub Dispose() Implements System.IDisposable.Dispose > Me.Items.Clear() > RaiseEvent Disposed(Me, System.EventArgs.Empty) > End Sub > #End Region > > #Region "IBindingList Sorting Features" > Private m_SupportsSorting As Boolean = True > Private m_SortProperty As PropertyDescriptor > Private m_SortDirection As ListSortDirection > Private m_OriginalList As ArrayList > > Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean > Get > Return m_SupportsSorting > End Get > End Property > Protected Overrides ReadOnly Property SortDirectionCore() As > System.ComponentModel.ListSortDirection > Get > Return m_SortDirection > End Get > End Property > > Protected Overrides ReadOnly Property SortPropertyCore() As > System.ComponentModel.PropertyDescriptor > Get > Return m_SortProperty > End Get > End Property > > Protected Overrides ReadOnly Property IsSortedCore() As Boolean > Get > Return m_SortProperty Is Nothing > End Get > End Property > > Private Sub SaveList() > m_OriginalList = New ArrayList(Me.Items) > End Sub > > Private Sub ResetList(ByVal NewList As ArrayList) > Me.ClearItems() > For Each m_T As T In NewList > Me.Add(m_T) > Next > End Sub > > Private Sub DoSort() > Dim m_Comparer As New clsListComparer(m_SortProperty, > m_SortDirection) > Dim m_SortList As New ArrayList(Me.Items) > m_SortList.Sort(m_Comparer) > ResetList(m_SortList) > End Sub > > Protected Overrides Sub ApplySortCore(ByVal prop As > System.ComponentModel.PropertyDescriptor, ByVal direction As > System.ComponentModel.ListSortDirection) > 'toegevoegd door Pieter want sorteerde enkel Ascending in een > DataGridView... > If m_SortProperty IsNot Nothing Then > If (m_SortProperty.Name = prop.Name) And (m_SortDirection = > direction) Then > 'wisselen! > direction = (direction + 1) Mod 2 > End If > End If > > m_SortProperty = prop > m_SortDirection = direction > If (m_OriginalList Is Nothing) Then > SaveList() > End If > DoSort() > End Sub > > Protected Overrides Sub RemoveSortCore() > ResetList(m_OriginalList) > m_SortDirection = Nothing > m_SortProperty = Nothing > End Sub > #End Region > > #Region "Private Variabel Declarations" > Private m_blnSavedSuccesfull As Boolean > Private m_blnDeletedSuccesfull As Boolean > Private m_blnCatchChanges As Boolean = True > Private m_blnHasChanges As Boolean = False > Private m_strEntiteName As String = "entité" > Private m_strEntiteCe As String = "cette" > Private m_blnSelected As Boolean = True > Private m_blnFilling As Boolean = False > Private m_blnThrowEveryChangesEvent As Boolean = False > #End Region > > #Region "Protected Variabel Declarations" > > #End Region > > #Region "Protected Methods" > ''' <name>Sub SaveBegin</name> > ''' <summary> > ''' Method to call at the beginning of a Save. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Protected Sub SaveBegin() > Me.SavedSuccesfull = True > End Sub > > ''' <name>Sub SaveEnd</name> > ''' <summary> > ''' Method to call at the end of a Save. Calls > SetClassToUnchangedState(). Must only be called on SavedSuccesfull. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Protected Sub SaveEnd() > If Me.SavedSuccesfull Then > 'Après qu'on a sauvegarder tout les info: donne la message > qu'on a tout bien sauvegarder et qu'on peut remttre le control dans un > état "pas de changements" > SetCollectionToUnchangedState() > Else > 'tell the user that his class wasn't saved succesfully! > End If > 'raise the event that the save has ended > 'RaiseEvent SaveHasEnded(Me, EventArgs.Empty) > End Sub > > ''' <name>Sub DeleteBegin</name> > ''' <summary> > ''' Method to call at the beginning of a Delete. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Protected Sub DeleteBegin() > Me.DeletedSuccesfull = True > End Sub > #End Region > > #Region "Public Propertys" > ''' <name>Property SavedSuccesfull</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' Indique si la classe a été sauvegarder avec succès. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property SavedSuccesfull() As Boolean > Get > Return m_blnSavedSuccesfull > End Get > Set(ByVal value As Boolean) > m_blnSavedSuccesfull = value > End Set > End Property > > ''' <name>Property DeletedSuccesfull</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' Indique si la classe a été supprimé avec succès. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property DeletedSuccesfull() As Boolean > Get > Return m_blnDeletedSuccesfull > End Get > Set(ByVal value As Boolean) > m_blnDeletedSuccesfull = value > End Set > End Property > > ''' <name>Property CatchChanges</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' Indique si le control doit réagir sur des changements ou pas: par > exemple pas pendant qu'on fait le load d'une entité... > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property CatchChanges() As Boolean > Get > Return m_blnCatchChanges > End Get > Set(ByVal value As Boolean) > m_blnCatchChanges = value > Dim clsI As clsBaseClass > For Each clsI In MyBase.Items > clsI.CatchChanges = m_blnCatchChanges > Next > End Set > End Property > > ''' <name>Property ThrowEveryChangesEvent</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' Indique qu'un evenement doit être raised à chaque changement, ou > seulement le premier fois... > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property ThrowEveryChangesEvent() As Boolean > Get > Return m_blnThrowEveryChangesEvent > End Get > Set(ByVal value As Boolean) > m_blnThrowEveryChangesEvent = value > End Set > End Property > > '<System.ComponentModel.DefaultValue(False)> _ > Public Event HasChangesEvent As EventHandler(Of HasChangesEventArgs) > ''' <name>Property HasChanges</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' True s'il y a des changements qui se sont passés aux propertys de > la classe. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property HasChanges() As Boolean > Get > Return m_blnHasChanges > End Get > Set(ByVal value As Boolean) > m_blnHasChanges = value > End Set > End Property > > ''' <name>Property EntiteName</name> > ''' <returns>String</returns> > ''' <summary> > ''' Le nom de l'entité de la classe. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property EntiteName() As String > Get > Return m_strEntiteName > End Get > Set(ByVal value As String) > m_strEntiteName = value > End Set > End Property > > ''' <name>Property EntiteCe</name> > ''' <returns>String</returns> > ''' <summary> > ''' CET adresse, CE fournisseur, ... > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Property EntiteCe() As String > Get > Return m_strEntiteCe > End Get > Set(ByVal value As String) > m_strEntiteCe = value > End Set > End Property > > #End Region > > #Region "Base Collection Methods" > ''' <name>Function TestCloseCollection</name> > ''' <returns>Integer</returns> > ''' <summary> > ''' This Methode tests for unsaved changes when CatchChanges is True, > and ask to save unchanged changes. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Function TestCloseCollection() As Integer > If Me.m_blnCatchChanges And Me.m_blnHasChanges Then > Dim intA As Integer > intA = MessageBox.Show("Vous avez fait des changements depuis > le dernier sauvegarde." & vbCrLf & "Est-ce que vous voulez les > sauvegarder?", "Sauvegarder changements?", MessageBoxButtons.YesNoCancel, > MessageBoxIcon.Warning) > > If intA = vbYes Then > 'raise event to save the changes > 'RaiseEvent Click_Save() > If Me.Save() Then > 'if succesfully saved: class can be > disposed/finalized... > Return vbYes > Else > 'if not: don't close it... > Return vbCancel > End If > ElseIf intA = vbNo Then > 'if they don't want to save the changes: disable the > changes-handler > Me.CatchChanges = False > Return intA > Else > Return intA > End If > Else > Return vbYes > End If > End Function > > ''' <name>Function Save</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' ' Update les changements ou insert les dans la base de données pour > tout les objets dans la collection. > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Function Save() As Boolean > Try > Me.SaveBegin() > Dim clsI As clsBaseClass > For Each clsI In MyBase.Items > If Not clsI.Save() Then SavedSuccesfull = False > Next > Catch ex As Exception > 'ErrorMessage(ex) > SavedSuccesfull = False > Throw ex > End Try > > Me.SaveEnd() > Return SavedSuccesfull > End Function > > ''' <name>Function Delete</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' Supprime tout les éléments dans la liste > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Function Delete() As Boolean > Try > Me.DeleteBegin() > Dim clsI As clsBaseClass > For Each clsI In MyBase.Items > If Not clsI.Delete Then > Me.DeletedSuccesfull = False > Return Me.DeletedSuccesfull > Exit Function > End If > Next > > 'remove them all > Me.Clear() > Catch ex As Exception > 'ErrorMessage(ex) > Me.DeletedSuccesfull = False > Throw ex > End Try > > Return Me.DeletedSuccesfull > End Function > > ''' <name>Function Delete</name> > ''' <returns>Boolean</returns> > ''' <summary> > ''' Deletes a specified Object in the List > ''' </summary> > ''' <param name="item">ByVal item As T: The item that must be > deleted</param> > ''' <history> > ''' PCO Created > ''' </history> > Public Function Delete(ByVal item As T) As Boolean > Try > Me.DeleteBegin() > If Not item.Delete Then Me.DeletedSuccesfull = False > Me.Remove(item) > Catch ex As Exception > 'ErrorMessage(ex) > Me.DeletedSuccesfull = False > Throw ex > End Try > > Return Me.DeletedSuccesfull > End Function > > ''' <name>Sub SetCollectionToUnchangedState</name> > ''' <summary> > ''' Methode qui remets le HasChanges = False et CatchChanges = True > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public Sub SetCollectionToUnchangedState() > 'reset it > CatchChanges = True > HasChanges = False > End Sub > > Private Sub OnObjectInListChangedHandler(ByVal sender As Object, ByVal > e As HasChangesEventArgs) > 'always... > ''regarde si on n'as pas déjà fait... > ''If (Not m_blnHasChanges) Then 'il y a une valeur qui est changé! > ''ok, il y a une valeur changé > HasChanges = True > RaiseEvent HasChangesEvent(sender, e) > ''End If > End Sub > > Private Sub OnObjectInListSelectedChangedHandler(ByVal sender As > Object, ByVal e As HasChangesEventArgs) > 'always... > RaiseEvent HasChangesSelectedEvent(sender, e) > End Sub > > Public Event HasChangesSelectedEvent As EventHandler(Of > HasChangesEventArgs) > > ''' <name>ReadOnly Property SelectedCount()</name> > ''' <returns>Integer</returns> > ''' <summary> > ''' Property qui retourne le nombre d'Items dans la collection qui a le > property Selected = True > ''' </summary> > ''' <history> > ''' PCO Created > ''' </history> > Public ReadOnly Property SelectedCount() As Integer > Get > Dim clsB As clsBaseClass > Dim intC As Integer = 0 > For Each clsB In MyBase.Items > If clsB.Selected Then > intC += 1 > End If > Next > Return intC > End Get > End Property > #End Region > > #Region "List Methods" > Public Shadows Sub Add(ByVal item As T) > item.SetClassToUnchangedState() > AddHandler item.HasChangesEvent, AddressOf > OnObjectInListChangedHandler > AddHandler item.SelectedChanged, AddressOf > OnObjectInListSelectedChangedHandler > MyBase.Add(item) > End Sub > > Public Shadows Sub Insert(ByVal index As Integer, ByVal item As T) > item.SetClassToUnchangedState() > AddHandler item.HasChangesEvent, AddressOf > OnObjectInListChangedHandler > AddHandler item.SelectedChanged, AddressOf > OnObjectInListSelectedChangedHandler > MyBase.Insert(index, item) > End Sub > > Public Shadows Sub Clear() > For Each item As clsBaseClass In Me > RemoveHandler item.HasChangesEvent, AddressOf > OnObjectInListChangedHandler > RemoveHandler item.SelectedChanged, AddressOf > OnObjectInListSelectedChangedHandler > Next > MyBase.Clear() > End Sub > > Public Shadows Function Remove(ByVal item As T) As Boolean > RemoveHandler item.HasChangesEvent, AddressOf > OnObjectInListChangedHandler > RemoveHandler item.SelectedChanged, AddressOf > OnObjectInListSelectedChangedHandler > Return MyBase.Remove(item) > End Function > > Public Shadows Sub RemoveAt(ByVal index As Integer) > RemoveHandler MyBase.Item(index).HasChangesEvent, AddressOf > OnObjectInListChangedHandler > RemoveHandler MyBase.Item(index).SelectedChanged, AddressOf > OnObjectInListSelectedChangedHandler > MyBase.RemoveAt(index) > End Sub > > 'very important, otherwise it will return objects of clsBaseClass, and > not object of T... > Default Public Shadows Property Item(ByVal index As Integer) As T > Get > Return MyBase.Item(index) > End Get > Set(ByVal value As T) > AddHandler value.HasChangesEvent, AddressOf > OnObjectInListChangedHandler > AddHandler value.SelectedChanged, AddressOf > OnObjectInListSelectedChangedHandler > MyBase.Item(index) = value > End Set > End Property > > #End Region > > #Region "Searching" > Protected Overrides ReadOnly Property SupportsSearchingCore() As > Boolean > Get > Return True > End Get > End Property > > ' Item property descriptor collection cache > Dim pdc As PropertyDescriptorCollection = Nothing > > Protected Overrides Function FindCore(ByVal [property] As > PropertyDescriptor, ByVal key As Object) As Integer > ' Specify search columns > If ([property] Is Nothing) Then > Return -1 > End If > > ' Get list to search > Dim items As List(Of T) = Me.Items > ' Traverse list for value > For Each item As T In items > ' Test column search value > Dim value As String = CStr([property].GetValue(item)) > 'If value is the search value, return the > ' index of the data item > If (CStr(key) = value) Then > Return IndexOf(item) > End If > Next item > Return -1 > End Function > > 'ByVal [property] As PropertyDescriptor, ByVal key As Object > Public Function FindItems(ByVal ColumnName As String, ByVal ColumnValue > As Object) As clsBaseList(Of T) > Dim lst As New clsBaseList(Of T) > Dim properties As PropertyDescriptorCollection > Dim myProperty As PropertyDescriptor > > ' Specify search columns > If (ColumnName Is Nothing) Then > Return Nothing > End If > > ' Get list to search > Dim items As List(Of T) = Me.Items > ' Traverse list for value > For Each item As T In items > properties = TypeDescriptor.GetProperties(item.GetType) > myProperty = properties.Find(ColumnName, False) > ' Test column search value > Dim value As String = CStr(myProperty.GetValue(item)) > 'If value is the search value, return the > ' index of the data item > If (CStr(ColumnValue) = value) Then > lst.Add(item) > End If > Next item > Return lst > End Function > > Public Function FindItem(ByVal ColumnName As String, ByVal ColumnValue > As Object) As T > Dim properties As PropertyDescriptorCollection = > TypeDescriptor.GetProperties(Me.Items(0).GetType) > Dim myProperty As PropertyDescriptor = properties.Find(ColumnName, > False) > Dim i As Integer = FindCore(myProperty, ColumnValue) > If i = -1 Then > Return Nothing > Else > Return Me.Item(i) > End If > End Function > > Public Function SumItems(ByVal ColumnName As String) As Decimal > Dim properties As PropertyDescriptorCollection > Dim myProperty As PropertyDescriptor > > ' Specify search columns > If (ColumnName Is Nothing) Then > Return Nothing > End If > > ' Get list to search > Dim items As List(Of T) = Me.Items > ' Traverse list for value > Dim decSum As Decimal = 0 > For Each item As T In items > properties = TypeDescriptor.GetProperties(item.GetType) > myProperty = properties.Find(ColumnName, False) > 'Dim value As String = CStr(myProperty.GetValue(item)) > decSum += CSng(myProperty.GetValue(item)) > Next item > Return decSum > End Function > > #End Region > > End Class > > Public Class clsListComparer > Implements IComparer > > Private m_SortList As ListSortDescriptionCollection > > Public Sub New(ByVal SortProperty As PropertyDescriptor, ByVal > direction As ListSortDirection) > 'Create a new list every time > m_SortList = New ListSortDescriptionCollection(New > ListSortDescription() {New ListSortDescription(SortProperty, direction)}) > End Sub > > Public Sub New(ByVal SortList As ListSortDescriptionCollection) > m_SortList = SortList > End Sub > > Private Function CompareSingleProperty(ByVal x As clsBaseClass, ByVal y > As clsBaseClass, ByVal prop As PropertyDescriptor, ByVal direction As > ListSortDirection) As Integer > Dim result As Integer = 0 > Dim directionModifier As Integer > If (direction = ListSortDirection.Ascending) Then > directionModifier = 1 > Else > directionModifier = -1 > End If > If (x Is Nothing) Then > result = -1 * directionModifier > ElseIf (y Is Nothing) Then > result = 1 * directionModifier > ElseIf (prop.GetValue(x) < prop.GetValue(y)) Then > result = -1 * directionModifier > ElseIf (prop.GetValue(x) > prop.GetValue(y)) Then > result = 1 * directionModifier > Else > result = 0 > End If > Return result > End Function > > Private Function Compare(ByVal x As Object, ByVal y As Object) As > Integer _ > Implements System.Collections.IComparer.Compare > Dim idx As Integer > Dim result As Integer > If (Not TypeOf x Is clsBaseClass) Then > Throw New ArgumentException("Unexpected Argument. Arguments > must be of Type ", "x") > End If > If (Not TypeOf y Is clsBaseClass) Then > Throw New ArgumentException("Unexpected Argument. Arguments > must be of Type ", "y") > End If > For idx = 0 To m_SortList.Count - 1 > result = CompareSingleProperty(x, y, > m_SortList(idx).PropertyDescriptor, m_SortList(idx).SortDirection) > If (result <> 0) Then > Exit For > End If > Next > Return result > End Function > End Class > > > > > "Arthur Dent" <hitchhikersguideto-n***@yahoo.com> wrote in message Well, that's exactly what I did: it is taken all the advantages of the news:%23oMIjloTGHA.5468@TK2MSFTNGP14.phx.gbl... >I could do that, but the thing is that that defeats the point of OO. I was >trying to take advantage of the generic collection as a base so i wouldnt >have to reinvent the wheel..... theres a lot of code involved in coding >collection classes. generic classes, it was a bit more difficult, but really worth it (I like generics): as you can see: "Public Class clsBaseList(Of T As clsBaseClass)". So I didn't reinvent the wheel here I think :) Althoug, in my particular case all my objects inherit from clsBaseClass, which handles a lot of common functionality for my objects. Arthur,
In addition to the other comments: Remember that Collection(Of T) is simply a wrapper for an object that implements IList(Of T). This wrapped IList(Of T) does all the "heavy lifting" the Collection(Of T) simply delegates to the wrapped IList(Of T). <sidenote>Read Collection(Of T) uses the Strategy Pattern. The IList(Of T) is the strategy it uses to implement the list itself, by default its uses an array like structure for the strategy (the List(Of T), you can easily replace the strategy with a LinkedList or a Binary tree, see below for details on replacing the strategy...</sidenote> You can use Collection(Of T).Items to get at the wrapped IList(Of T). By default Collection(Of T) uses a List(Of T) as the wrapped IList(Of T), List(Of T) has a Sort method (plus a plethora of other methods). Collection(Of T).Items is how you get at the wrapped IList(Of T). In other words casting Collection(Of T).Items to List(Of T) should allow you to call its Sort method. Something like: Public Class Person Implements IComparable(Of Person) ... Public Function CompareTo(ByVal other As Person) As Integer Implements System.IComparable(Of Person).CompareTo ... End Function End Class Public Class PersonCollection Inherits ObjectModel.Collection(Of Person) Public Sub Sort() DirectCast(Items, List(Of Person)).Sort() End Sub End Class I would consider introducing a new generic collection base that incorporates this sorting: Public Class CollectionBase(Of T) Inherits ObjectModel.Collection(Of T) Public Sub Sort() DirectCast(Items, List(Of T)).Sort() End Sub Public Sub Sort(ByVal comparer As IComparer(Of T)) DirectCast(Items, List(Of T)).Sort(comparer) End Sub Public Sub Sort(ByVal index As Integer, ByVal count As Integer, ByVal comparer As IComparer(Of T)) DirectCast(Items, List(Of T)).Sort(index, count, comparer) End Sub Public Sub Sort(ByVal comparison As Comparison(Of T)) DirectCast(Items, List(Of T)).Sort(comparison) End Sub End Class Then PersonCollection would be based on this new base: Public Class PersonCollection Inherits CollectionBase(Of Person) End Class NOTE: The above may fail if you call Collection(Of T).New(IList(Of T)) passing in a something other then List(Of T). For example: Public Class PersonCollection Inherits ObjectModel.Collection(Of Person) ' use a linked list strategy Public Sub New() MyBase.New(New LinkedList(Of Person)) End Sub ' use an array strategy Public Sub New() MyBase.New(New Person(100-1) {}) ' base it on an 100 element array End Sub ' use some other generic collection strategy ' where SpecializedCollection implements IList(Of T) Public Sub New() MyBase.New(New SpecializedCollection(Of Person)) End Sub End Class The Frameworks LinkedList(Of T) does not implement IList(Of T) although it is easy to add. The array does work (as the wrapped list), giving you a fixed sized collection that you cannot add or remove elements from (you can only change existing entries)... I have not yet posted my sample LinkedList(Of T) that implements IList(Of T) to my web site... -- Show quoteHide quoteHope this helps Jay [MVP - Outlook] ..NET Application Architect, Enthusiast, & Evangelist T.S. Bradley - http://www.tsbradley.net "Arthur Dent" <hitchhikersguideto-n***@yahoo.com> wrote in message news:eAOTJuVTGHA.1728@TK2MSFTNGP11.phx.gbl... | How do you sort a generic collection derived from | System.Collections.ObjectModel.Collection? | | Thanks in advance, | - Arthur Dent | | Thank you, that was exactly what i was looking for, getting at the inner
list object to be able to use its methods. Cheers! Show quoteHide quote "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in message news:eUytha0TGHA.2276@tk2msftngp13.phx.gbl... > Arthur, > In addition to the other comments: > > > Remember that Collection(Of T) is simply a wrapper for an object that > implements IList(Of T). This wrapped IList(Of T) does all the "heavy > lifting" the Collection(Of T) simply delegates to the wrapped IList(Of T). > <sidenote>Read Collection(Of T) uses the Strategy Pattern. The IList(Of > T) > is the strategy it uses to implement the list itself, by default its uses > an > array like structure for the strategy (the List(Of T), you can easily > replace the strategy with a LinkedList or a Binary tree, see below for > details on replacing the strategy...</sidenote> > > You can use Collection(Of T).Items to get at the wrapped IList(Of T). > > By default Collection(Of T) uses a List(Of T) as the wrapped IList(Of T), > List(Of T) has a Sort method (plus a plethora of other methods). > Collection(Of T).Items is how you get at the wrapped IList(Of T). In other > words casting Collection(Of T).Items to List(Of T) should allow you to > call > its Sort method. > > Something like: > > Public Class Person > Implements IComparable(Of Person) > > ... > > Public Function CompareTo(ByVal other As Person) As Integer > Implements System.IComparable(Of Person).CompareTo > ... > End Function > > End Class > > Public Class PersonCollection > Inherits ObjectModel.Collection(Of Person) > > Public Sub Sort() > DirectCast(Items, List(Of Person)).Sort() > End Sub > > End Class > > I would consider introducing a new generic collection base that > incorporates > this sorting: > > Public Class CollectionBase(Of T) > Inherits ObjectModel.Collection(Of T) > > Public Sub Sort() > DirectCast(Items, List(Of T)).Sort() > End Sub > > Public Sub Sort(ByVal comparer As IComparer(Of T)) > DirectCast(Items, List(Of T)).Sort(comparer) > End Sub > > Public Sub Sort(ByVal index As Integer, ByVal count As Integer, > ByVal comparer As IComparer(Of T)) > DirectCast(Items, List(Of T)).Sort(index, count, comparer) > End Sub > > Public Sub Sort(ByVal comparison As Comparison(Of T)) > DirectCast(Items, List(Of T)).Sort(comparison) > End Sub > > End Class > > Then PersonCollection would be based on this new base: > > Public Class PersonCollection > Inherits CollectionBase(Of Person) > > End Class > > > NOTE: The above may fail if you call Collection(Of T).New(IList(Of T)) > passing in a something other then List(Of T). For example: > > Public Class PersonCollection > Inherits ObjectModel.Collection(Of Person) > > ' use a linked list strategy > Public Sub New() > MyBase.New(New LinkedList(Of Person)) > End Sub > > ' use an array strategy > Public Sub New() > MyBase.New(New Person(100-1) {}) ' base it on an 100 element > array > End Sub > > ' use some other generic collection strategy > ' where SpecializedCollection implements IList(Of T) > Public Sub New() > MyBase.New(New SpecializedCollection(Of Person)) > End Sub > > End Class > > The Frameworks LinkedList(Of T) does not implement IList(Of T) although it > is easy to add. The array does work (as the wrapped list), giving you a > fixed sized collection that you cannot add or remove elements from (you > can > only change existing entries)... > > I have not yet posted my sample LinkedList(Of T) that implements IList(Of > T) > to my web site... > > -- > Hope this helps > Jay [MVP - Outlook] > .NET Application Architect, Enthusiast, & Evangelist > T.S. Bradley - http://www.tsbradley.net > > > "Arthur Dent" <hitchhikersguideto-n***@yahoo.com> wrote in message > news:eAOTJuVTGHA.1728@TK2MSFTNGP11.phx.gbl... > | How do you sort a generic collection derived from > | System.Collections.ObjectModel.Collection? > | > | Thanks in advance, > | - Arthur Dent > | > | > > Arthur,
Thinking about it, it might be better to ensure that you have a wrapped List(Of T) verses some other IList(Of T) collection... Especially when introducing a new generic base class... | > Public Class CollectionBase(Of T) Public Sub New()| > Inherits ObjectModel.Collection(Of T) | > MyBase.New() End Sub Public Sub New(list As IList(Of T)) MyBase.New(list) End Sub | > Public Sub Sort() Dim list As List(Of T) = TryCast(Items, List(Of T))If list Is Nothing Then Throw New NotSupportedException() list.Sort() | > End Sub | > -- Show quoteHide quoteHope this helps Jay [MVP - Outlook] ..NET Application Architect, Enthusiast, & Evangelist T.S. Bradley - http://www.tsbradley.net "Arthur Dent" <hitchhikersguideto-n***@yahoo.com> wrote in message news:%23YskK%238TGHA.4540@TK2MSFTNGP10.phx.gbl... | Thank you, that was exactly what i was looking for, getting at the inner | list object to be able to use its methods. | Cheers! | | | "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in | message news:eUytha0TGHA.2276@tk2msftngp13.phx.gbl... | > Arthur, | > In addition to the other comments: | > | > | > Remember that Collection(Of T) is simply a wrapper for an object that | > implements IList(Of T). This wrapped IList(Of T) does all the "heavy | > lifting" the Collection(Of T) simply delegates to the wrapped IList(Of T). | > <sidenote>Read Collection(Of T) uses the Strategy Pattern. The IList(Of | > T) | > is the strategy it uses to implement the list itself, by default its uses | > an | > array like structure for the strategy (the List(Of T), you can easily | > replace the strategy with a LinkedList or a Binary tree, see below for | > details on replacing the strategy...</sidenote> | > | > You can use Collection(Of T).Items to get at the wrapped IList(Of T). | > | > By default Collection(Of T) uses a List(Of T) as the wrapped IList(Of T), | > List(Of T) has a Sort method (plus a plethora of other methods). | > Collection(Of T).Items is how you get at the wrapped IList(Of T). In other | > words casting Collection(Of T).Items to List(Of T) should allow you to | > call | > its Sort method. | > | > Something like: | > | > Public Class Person | > Implements IComparable(Of Person) | > | > ... | > | > Public Function CompareTo(ByVal other As Person) As Integer | > Implements System.IComparable(Of Person).CompareTo | > ... | > End Function | > | > End Class | > | > Public Class PersonCollection | > Inherits ObjectModel.Collection(Of Person) | > | > Public Sub Sort() | > DirectCast(Items, List(Of Person)).Sort() | > End Sub | > | > End Class | > | > I would consider introducing a new generic collection base that | > incorporates | > this sorting: | > | > Public Class CollectionBase(Of T) | > Inherits ObjectModel.Collection(Of T) | > | > Public Sub Sort() | > DirectCast(Items, List(Of T)).Sort() | > End Sub | > | > Public Sub Sort(ByVal comparer As IComparer(Of T)) | > DirectCast(Items, List(Of T)).Sort(comparer) | > End Sub | > | > Public Sub Sort(ByVal index As Integer, ByVal count As Integer, | > ByVal comparer As IComparer(Of T)) | > DirectCast(Items, List(Of T)).Sort(index, count, comparer) | > End Sub | > | > Public Sub Sort(ByVal comparison As Comparison(Of T)) | > DirectCast(Items, List(Of T)).Sort(comparison) | > End Sub | > | > End Class | > | > Then PersonCollection would be based on this new base: | > | > Public Class PersonCollection | > Inherits CollectionBase(Of Person) | > | > End Class | > | > | > NOTE: The above may fail if you call Collection(Of T).New(IList(Of T)) | > passing in a something other then List(Of T). For example: | > | > Public Class PersonCollection | > Inherits ObjectModel.Collection(Of Person) | > | > ' use a linked list strategy | > Public Sub New() | > MyBase.New(New LinkedList(Of Person)) | > End Sub | > | > ' use an array strategy | > Public Sub New() | > MyBase.New(New Person(100-1) {}) ' base it on an 100 element | > array | > End Sub | > | > ' use some other generic collection strategy | > ' where SpecializedCollection implements IList(Of T) | > Public Sub New() | > MyBase.New(New SpecializedCollection(Of Person)) | > End Sub | > | > End Class | > | > The Frameworks LinkedList(Of T) does not implement IList(Of T) although it | > is easy to add. The array does work (as the wrapped list), giving you a | > fixed sized collection that you cannot add or remove elements from (you | > can | > only change existing entries)... | > | > I have not yet posted my sample LinkedList(Of T) that implements IList(Of | > T) | > to my web site... | > | > -- | > Hope this helps | > Jay [MVP - Outlook] | > .NET Application Architect, Enthusiast, & Evangelist | > T.S. Bradley - http://www.tsbradley.net | > | > | > "Arthur Dent" <hitchhikersguideto-n***@yahoo.com> wrote in message | > news:eAOTJuVTGHA.1728@TK2MSFTNGP11.phx.gbl... | > | How do you sort a generic collection derived from | > | System.Collections.ObjectModel.Collection? | > | | > | Thanks in advance, | > | - Arthur Dent | > | | > | | > | > | |
Object variable or With block variable not set
PrintPreview problem Page_Load vs Submit_Click - which one first? Creating a CSV from query results Sending emails to multiple recipients ADO RowState problem sql question rounding time How are items added to VB2003 Tools menu item list box to combo box |
|||||||||||||||||||||||