Este documento muestra la forma de ordenar una colección de objetos observable mediante [IComparer]
Para ordenar una colección observable hay que seguir los siguientes pasos.
''' <summary> ''' Esta clase representa a una foto ''' </summary> <Serializable> Public Class UnaFoto '----------------------------- #Region "Variables y propiedades de la clase" Private _fileInfoImagen As System.IO.FileInfo Private _uriFullName As Uri = Nothing Private _strFullName As String Private _strName As String Private _dateCreationTime As Date ''' <summary> ''' Obtiene el nombre y la extension de la imagen ''' </summary> Public ReadOnly Property Name() As String Get Return _strName End Get End Property ''' <summary> ''' Obtiene la ruta completa (directorio + nombre + extension) de la imagen ''' </summary> Public ReadOnly Property FullName() As String Get Return _strFullName End Get End Property ''' <summary> ''' Obtiene el nombre y la extension de la imagen ''' </summary> Public ReadOnly Property UriFullName As Uri Get If _uriFullName Is Nothing Then _uriFullName = New Uri(FullName, UriKind.RelativeOrAbsolute) End If Return _uriFullName End Get End Property ''' <summary> ''' Obtiene la fecha de creación del fichero imagen ''' </summary> Public ReadOnly Property DateCreationTime() As Date Get Return _dateCreationTime End Get End Property #End Region #Region "Constructores" ''' <summary> ''' Constructor ''' </summary> ''' <param name=pfileInfoImagen">El valor del objeto FileInfo del fichero de la imagen</param>" Public Sub New(ByVal pfileInfoImagen As System.IO.FileInfo) pfileInfoImagen.Refresh() _fileInfoImagen = pfileInfoImagen _strFullName = pfileInfoImagen.FullName _strName = pfileInfoImagen.Name _dateCreationTime = pfileInfoImagen.CreationTime End Sub #End Region #Region "Interfaz IComparer " ' Métodos auxiliares que devuelven la interfaz ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por nombre completo (ruta + nombre + extension) ''' </summary> Public Shared Function GetIComparerPorNombreCompleto(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorNombreCompleto(tipoOrdenacion) End Function ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por nombre y la extension unicamente ''' </summary> Public Shared Function GetIComparerPorNombre(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorNombre(tipoOrdenacion) End Function ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por fecha de creación del fichero ''' </summary> Public Shared Function GetIComparerPorFechaCreacion(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorFechaCreacion(tipoOrdenacion) End Function #End Region End Class
''' <summary> ''' Clase auxiliar para comparar por nombre completo (ruta + nombre + extension) ''' </summary> Private Class CompararPorNombreCompleto Implements IComparer(Of UnaFoto) ''' <summary> Para ordenaciones ascendentes o descendentes </summary> Private _modificadorSortOrder As Integer = 1 ''' <summary> Constructor</summary> ''' <param name=tipoOrdenacion">Tipo de ordenación [Ascendente, descendente, no definida]</param>" ''' <remarks>Utilizo una enumeración de .Net, para no tener que definir una ex profeso</remarks> Public Sub New(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Select Case tipoOrdenacion Case Is = System.Data.SqlClient.SortOrder.Descending _modificadorSortOrder = -1 Case Is = System.Data.SqlClient.SortOrder.Ascending _modificadorSortOrder = +1 Case Is = System.Data.SqlClient.SortOrder.Unspecified _modificadorSortOrder = +1 End Select End Sub ''' <summary> ''' Compara dos objetos y devuelve un valor que indica si uno es menor, igual o mayor que el otro. ''' </summary> ''' <param name=x">La primera imagen</param>" ''' <param name=y">La segunda imagen</param>" ''' <returns> ''' <para>Tipo: System.Int32 </para> ''' <para> Menor que cero (-1) x es menor que y. </para> ''' <para> Cero ( 0) x es igual que y. </para> ''' <para> Mayor que cero (+1) x es mayor que y. </para> '''</returns> Public Function Compare(x As UnaFoto, y As UnaFoto) As Integer Implements IComparer(Of UnaFoto).Compare ' dos objetos nulos son iguales If x Is Nothing AndAlso y Is Nothing Then Return 0 ' cualquier objeto no nulo es mayor que un objeto nulo If x Is Nothing Then Return 1 If y Is Nothing Then Return -1 ' realizar la comparación Dim resultadoComparacion As Integer = String.Compare(x.FullName, y.FullName) ' modificación ascendente o descendente Return resultadoComparacion * _modificadorSortOrder End Function End Class ''' <summary> ''' Clase auxiliar para comparar por nombre y la extension unicamente ''' </summary> Private Class CompararPorNombre Implements IComparer(Of UnaFoto) Private _modificadorSortOrder As Integer = 1 Public Sub New(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Select Case tipoOrdenacion Case Is = System.Data.SqlClient.SortOrder.Descending _modificadorSortOrder = -1 Case Is = System.Data.SqlClient.SortOrder.Ascending _modificadorSortOrder = +1 Case Is = System.Data.SqlClient.SortOrder.Unspecified _modificadorSortOrder = +1 End Select End Sub Public Function Compare(x As UnaFoto, y As UnaFoto) As Integer Implements IComparer(Of UnaFoto).Compare ' dos objetos nulos son iguales If x Is Nothing AndAlso y Is Nothing Then Return 0 ' cualquier objeto no nulo es mayor que un objeto nulo If x Is Nothing Then Return 1 If y Is Nothing Then Return -1 ' realizar la comparación Dim resultadoComparacion As Integer = String.Compare(x.Name, y.Name) ' modificación ascendente o descendente Return resultadoComparacion * _modificadorSortOrder End Function End Class ''' <summary> ''' Clase auxiliar para comparar por fecha de creación del fichero ''' </summary> Private Class CompararPorFechaCreacion Implements IComparer(Of UnaFoto) Private _modificadorSortOrder As Integer = 1 Public Sub New(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Select Case tipoOrdenacion Case Is = System.Data.SqlClient.SortOrder.Descending _modificadorSortOrder = -1 Case Is = System.Data.SqlClient.SortOrder.Ascending _modificadorSortOrder = +1 Case Is = System.Data.SqlClient.SortOrder.Unspecified _modificadorSortOrder = +1 End Select End Sub Public Function Compare(x As UnaFoto, y As UnaFoto) As Integer Implements IComparer(Of UnaFoto).Compare ' dos objetos nulos son iguales If x Is Nothing AndAlso y Is Nothing Then Return 0 ' cualquier objeto no nulo es mayor que un objeto nulo If x Is Nothing Then Return 1 If y Is Nothing Then Return -1 ' realizar la comparación Dim resultadoComparacion As Integer = Date.Compare(x.DateCreationTime, y.DateCreationTime) ' modificación ascendente o descendente Return resultadoComparacion * _modificadorSortOrder End Function End Class
' (Funciones que estan en la clase UnaFoto) ' Métodos auxiliares que devuelven la interfaz ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por nombre completo (ruta + nombre + extension) ''' </summary> Public Shared Function GetIComparerPorNombreCompleto(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorNombreCompleto(tipoOrdenacion) End Function ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por nombre y la extension unicamente ''' </summary> Public Shared Function GetIComparerPorNombre(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorNombre(tipoOrdenacion) End Function ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por fecha de creación del fichero ''' </summary> Public Shared Function GetIComparerPorFechaCreacion(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorFechaCreacion(tipoOrdenacion) End Function
Imports System.Collections.ObjectModel Imports System.Collections.Specialized ''' <summary> ''' Esta clase representa a una colección de fotos en un directorio ''' </summary> Public Class ColecccionDeFotos Inherits ObservableCollection(Of UnaFoto) Private _directorio As System.IO.DirectoryInfo Public Sub New() 'Me.New(New System.IO.DirectoryInfo("F:\Fotos\")) End Sub Public Sub New(path As String) Me.New(New System.IO.DirectoryInfo(path)) End Sub Public Sub New(directory As System.IO.DirectoryInfo) _directorio = directory Update(_directorio) End Sub Public Property Path() As String Get Return _directorio.FullName End Get Set If String.Equals(_directorio.FullName, Value) = False Then _directorio = New System.IO.DirectoryInfo(Value) Update(_directorio) End If End Set End Property Private Sub Update(ByVal pdirectorio As System.IO.DirectoryInfo) Try 'Dim directorio As New DirectoryInfo(Fi.FullName) Dim ficherosDirectorio As System.IO.FileInfo() = pdirectorio.GetFiles If ficherosDirectorio.Count > 0 Then Me.Clear() For Each unFichero As System.IO.FileInfo In ficherosDirectorio ' excluir ficheros ocultos - exclude hidden files If (unFichero.Attributes And System.IO.FileAttributes.Hidden) <> System.IO.FileAttributes.Hidden Then ' excluir ficheros que no sean images If unFichero.Extension.ToLower = ".jpg" OrElse unFichero.Extension.ToLower = ".jpeg" OrElse unFichero.Extension.ToLower = ".png" OrElse unFichero.Extension.ToLower = ".tif" Then 'Dim nuevaFoto As New Foto(unFichero) 'Add(nuevaFoto) Add(New UnaFoto(unFichero)) End If End If Next End If Catch ex As System.IO.DirectoryNotFoundException Throw Catch ex As Exception Throw End Try End Sub Public ReadOnly Property ListaItemsCollections As ObservableCollection(Of UnaFoto) Get Return Me End Get End Property 'Protected Friend Shadows Sub RemoveItem(index As Integer) ' MyBase.RemoveItem(0) 'End Sub ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por nombre completo (ruta + nombre + extension) ''' </summary> Public Sub OrdenarPorNombreCompleto(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Dim arrayAux As UnaFoto() = MyBase.ToArray System.Array.Sort(arrayAux, UnaFoto.GetIComparerPorNombreCompleto(tipoOrdenacion)) Me.Clear() For Each unFichero As UnaFoto In arrayAux Add(unFichero) Next End Sub ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por nombre y la extension unicamente ''' </summary> Public Sub OrdenarPorNombre(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Dim arrayAux As UnaFoto() = MyBase.ToArray System.Array.Sort(arrayAux, UnaFoto.GetIComparerPorNombre(tipoOrdenacion)) Me.Clear() For Each unFichero As UnaFoto In arrayAux Add(unFichero) Next End Sub ''' <summary> ''' Devuelve la interfaz [IComparer] para comparar por fecha de creación del fichero ''' </summary> Public Sub OrdenarPorFechaCreacion(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Dim arrayAux As UnaFoto() = MyBase.ToArray System.Array.Sort(arrayAux, UnaFoto.GetIComparerPorFechaCreacion(tipoOrdenacion)) Me.Clear() For Each unFichero As UnaFoto In arrayAux Add(unFichero) Next End Sub End Class
Lo más importante es fijarse en la secuencia de funciones
''' <summary> ''' Clase [UnaFoto] Devuelve la interfaz [IComparer] para comparar por fecha de creación del fichero ''' </summary> Public Shared Function GetIComparerPorFechaCreacion(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) As IComparer(Of UnaFoto) Return New CompararPorFechaCreacion(tipoOrdenacion) End Function
Observa el juego que hay que hacer para que la ventana actualice la información de la colección una vez ordenada.
''' <summary> ''' Clase [ ObservableCollection(Of UnaFoto)] ''' Devuelve la interfaz [IComparer] para comparar por fecha de creación del fichero ''' </summary> Public Sub OrdenarPorFechaCreacion(ByVal tipoOrdenacion As System.Data.SqlClient.SortOrder) Dim arrayAux As UnaFoto() = MyBase.ToArray System.Array.Sort(arrayAux, UnaFoto.GetIComparerPorFechaCreacion(tipoOrdenacion)) Me.Clear() For Each unFichero As UnaFoto In arrayAux Add(unFichero) Next End Sub
El formulario llamador definirá mediante botones y/o menús, la forma de ordenación, y los eventos Clic llamaran a una de estas funciones.
Private Sub OrdenarPorFechaCreacionAscendente() coleccionFotos.OrdenarPorFechaCreacion(System.Data.SqlClient.SortOrder.Ascending) End Sub Private Sub OrdenarPorFechaCreacionDescendente() coleccionFotos.OrdenarPorFechaCreacion(System.Data.SqlClient.SortOrder.Descending) End Sub
© 1997 - - La Güeb de Joaquín | |||||
Joaquín Medina Serrano
|
|||||
|
Codificación | |
Fecha de creación | |
Última actualización | |
![]() |