elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Listview, ¿ordenar el contenido al clickar sobre una columna?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Listview, ¿ordenar el contenido al clickar sobre una columna?  (Leído 12,737 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Listview, ¿ordenar el contenido al clickar sobre una columna?
« en: 31 Diciembre 2012, 13:40 pm »

¿Me pueden decir alguna manera sencilla para ordenar alfabéticamente la columna de "problem" al pulsar click sobre el nombre de la columna?

O al menos, ¿Como se llama el evento que debo manejar? :S

Gracias.



« Última modificación: 18 Enero 2013, 11:18 am por EleKtro H@cker » En línea

seba123neo


Desconectado Desconectado

Mensajes: 3.621



Ver Perfil WWW
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #1 en: 31 Diciembre 2012, 14:43 pm »

hay varias maneras pero una de las mejores es usar la interface llamada IComparer. aca te paso la clase que usaba:

Código
  1. Public Class COrdenarListview
  2.    Implements IComparer
  3.  
  4.    Private vIndiceColumna As Integer
  5.    Private vTipoOrden As SortOrder
  6.  
  7.    Public Sub New(ByVal pIndiceColumna As Integer, ByVal pTipoOrden As SortOrder)
  8.        vIndiceColumna = pIndiceColumna
  9.        vTipoOrden = pTipoOrden
  10.    End Sub
  11.  
  12.    Public Function Ordenar(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
  13.        Dim item_x As ListViewItem = DirectCast(x, ListViewItem)
  14.        Dim item_y As ListViewItem = DirectCast(y, ListViewItem)
  15.  
  16.        Dim string_x As String
  17.  
  18.        If item_x.SubItems.Count <= vIndiceColumna Then
  19.            string_x = ""
  20.        Else
  21.            string_x = item_x.SubItems(vIndiceColumna).Text
  22.        End If
  23.  
  24.        Dim string_y As String
  25.        If item_y.SubItems.Count <= vIndiceColumna Then
  26.            string_y = ""
  27.        Else
  28.            string_y = item_y.SubItems(vIndiceColumna).Text
  29.        End If
  30.  
  31.        If vTipoOrden = SortOrder.Ascending Then
  32.            If IsNumeric(string_x) And IsNumeric(string_y) Then
  33.                Return Val(string_x).CompareTo(Val(string_y))
  34.            ElseIf IsDate(string_x) And IsDate(string_y) Then
  35.                Return DateTime.Parse(string_x).CompareTo(DateTime.Parse(string_y))
  36.            Else
  37.                Return String.Compare(string_x, string_y)
  38.            End If
  39.        Else
  40.            If IsNumeric(string_x) And IsNumeric(string_y) Then
  41.                Return Val(string_y).CompareTo(Val(string_x))
  42.            ElseIf IsDate(string_x) And IsDate(string_y) Then
  43.                Return DateTime.Parse(string_y).CompareTo(DateTime.Parse(string_x))
  44.            Else
  45.                Return String.Compare(string_y, string_x)
  46.            End If
  47.        End If
  48.    End Function
  49. End Class

luego para usarla tenes que usar el evento ColumnClick de esta forma:

Código
  1. Private Sub lv_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lv.ColumnClick
  2.  
  3.        Dim vIndiceColumna As ColumnHeader = lv.Columns(e.Column)
  4.  
  5.        Dim vTipoOrden As System.Windows.Forms.SortOrder
  6.  
  7.        If vColumnaOrden Is Nothing Then
  8.            vTipoOrden = SortOrder.Ascending
  9.            vOrden = SortOrder.Ascending
  10.        Else
  11.            If vIndiceColumna.Equals(vColumnaOrden) Then
  12.                If vOrden = SortOrder.Ascending Then
  13.                    vTipoOrden = SortOrder.Descending
  14.                    vOrden = SortOrder.Descending
  15.                Else
  16.                    vTipoOrden = SortOrder.Ascending
  17.                    vOrden = SortOrder.Ascending
  18.                End If
  19.            Else
  20.                vTipoOrden = SortOrder.Ascending
  21.                vOrden = SortOrder.Ascending
  22.            End If
  23.        End If
  24.  
  25.        vColumnaOrden = vIndiceColumna
  26.  
  27.        lv.ListViewItemSorter = New COrdenarListview(e.Column, vTipoOrden)
  28.        lv.Sort()
  29.    End Sub

esta lo que hace es que te "detecta" por asi decirlo, el tipo de datos de la columna y te lo ordena dependiendo ese tipo de dato, por ejemplo si tenes numeros te lo ordena como numero y no como string, te detecta las fechas y los strings comunes, y tiene los 2 metodos ascendente y descendente.

digo "usaba", porque desde hace rato ya en .NET uso el ObjectListview, es lejos el mejor control creado para .NET, el cual te facilita todo, es mil veces mejor que el Listview de .NET, y tambien te hace todo automatico el tema del ordenamiento. te ahorras todo estos temas de ensuciar el codigo con cada cosita extra que uno necesita hacer.

saludos.


En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #2 en: 31 Diciembre 2012, 16:23 pm »

A mi me gustaría usar el objectlistview pero no tengo ni idea de como añadir un item,
Seba123Neo, ¿Serías tán amable de enseñarme como crear/agregar un objeto para añadirlo al ObjectListView?, es decir, un item. ¿?
Lo intenté hacer pero es distinto de hacer como se haría con el ListView normal.

PD: Gracias por la class.
En línea

seba123neo


Desconectado Desconectado

Mensajes: 3.621



Ver Perfil WWW
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #3 en: 31 Diciembre 2012, 16:53 pm »

en el objectlistview los items no se agregan como en el comun, justamente se llama "object" porque se maneja todo con objetos, o sea tenes que crear una clase con las propiedades (que serian las columnas) que va a tener el listview y entonces despues asignas esa clase al listview y automaticamente te lo detecta y se arma solo. para llenar items simplemente creas una lista de las clase es que creas y las vas llenado con datos,  cada clase despues seria un registro. si te bajas este control ya viene con un proyecto de como se usa, esta en C# pero se entiende bien la logica.

despues creo un post mostrando como se usa.
« Última modificación: 31 Diciembre 2012, 16:54 pm por seba123neo » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #4 en: 31 Diciembre 2012, 17:28 pm »

despues creo un post mostrando como se usa.

Deseando ver el mini-tutorial ;D, nos servirá a todos, además es un magnifico control.

PD: La explicación se me ha quedado corta XD, de todas formas lo intentaré a ver...

Saludos
En línea

spiritdead

Desconectado Desconectado

Mensajes: 296


Ver Perfil
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #5 en: 1 Enero 2013, 00:24 am »

Deseando ver el mini-tutorial ;D, nos servirá a todos, además es un magnifico control.

PD: La explicación se me ha quedado corta XD, de todas formas lo intentaré a ver...

Saludos

si lo necesitas urgente, avisame y por teamviewver se te enseña rapido, dificil no es XD
En línea

Facilitador De Tareas - Task Simplifier (FDT)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #6 en: 8 Enero 2013, 18:28 pm »

si lo necesitas urgente, avisame y por teamviewver se te enseña rapido, dificil no es XD

Gracias spiritdead pero no me urge, aún estoy aprendiendo a usar el listview convencional.



@seba123Neo

¿Como lo hago funcionar?

Me da error en las variables:
Código:
vColumnaOrden
    vOrden
Dicen que no están declaradas, y no se con que tipo de valor debo setearlas ni nada xD

Código
  1.  Private Sub GListView_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles GListView.ColumnClick
  2.  
  3.        Dim vIndiceColumna As ColumnHeader = GListView.Columns(e.Column)
  4.  
  5.        Dim vTipoOrden As System.Windows.Forms.SortOrder
  6.  
  7.        If vColumnaOrden Is Nothing Then
  8.            vTipoOrden = SortOrder.Ascending
  9.            vOrden = SortOrder.Ascending
  10.        Else
  11.            If vIndiceColumna.Equals(vColumnaOrden) Then
  12.                If vOrden = SortOrder.Ascending Then
  13.                    vTipoOrden = SortOrder.Descending
  14.                    vOrden = SortOrder.Descending
  15.                Else
  16.                    vTipoOrden = SortOrder.Ascending
  17.                    vOrden = SortOrder.Ascending
  18.                End If
  19.            Else
  20.                vTipoOrden = SortOrder.Ascending
  21.                vOrden = SortOrder.Ascending
  22.            End If
  23.        End If
  24.  
  25.        vColumnaOrden = vIndiceColumna
  26.  
  27.        GListView.ListViewItemSorter = New COrdenarListview(e.Column, vTipoOrden)
  28.        GListView.Sort()
  29.    End Sub



EDITO:
Seba123Neo, si no he captado mal la idea, al final lo he hecho así, y funciona bien, pero no sé si es peor que tu snippet:



Código
  1.  
  2. ' En las declaraciones...
  3. Dim ColumnOrder As String = "Down"
  4.  
  5.  
  6. Private Sub GListView_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles GListView.ColumnClick
  7.        If ColumnOrder = "Down" Then
  8.            Me.GListView.ListViewItemSorter = New COrdenarListview(e.Column, SortOrder.Ascending)
  9.            GListView.Sort()
  10.            ColumnOrder = "Up"
  11.        ElseIf ColumnOrder = "Up" Then
  12.            Me.GListView.ListViewItemSorter = New COrdenarListview(e.Column, SortOrder.Descending)
  13.            GListView.Sort()
  14.            ColumnOrder = "Down"
  15.        End If
  16.    End Sub
« Última modificación: 8 Enero 2013, 19:28 pm por EleKtro H@cker » En línea

phetete

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #7 en: 12 Enero 2016, 21:00 pm »

estimados:

he probado el codigo fuente y tambien otro muy similar de el guille, y ambos me resultan muy lentos. aproximadamente 30 segundos para una tabla 30 filas y 2 columnas...!!!

al hacer clic en la primera columna que solo tiene numeros no hay problema, pero al ordenar por la segunda columna, que es texto, se demora demasiado.

alguna sugerencia... pese a que han pasado pvarios años desde el ultimo post.

pd: estoy trabajando en vb.net 2010.

saludos.
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.788



Ver Perfil
Re: Listview, ¿ordenar el contenido al clickar sobre una columna?
« Respuesta #8 en: 12 Enero 2016, 21:32 pm »

alguna sugerencia...

El código del compañero @seba123Neo y cualquier comparer en general no tiene misterio, se implementa la interfáz IComparer o un type que la implemente (ej. para texto: CaseInsensitiveComparer) y se implementan los métodos base, es el modelo standard a seguir para implementar dicha funcionalidad de manera correcta, así que si te tarda digamos más de 2 segundos en ordenar entonces seguramente el problema es ajeno al comparer.

· ¿Tal vez estés utilizando un listview de terceros que sea muy "pesado", o una cantidad de datos muy "pesada"?.

· Si las circunstancias lo permiten siempre puedes probar a utilizar el modo virtual para aumentar en gran medida el rendimiento del listview:
De todas formas, eso es solo una sugerencia adicional y ajena al problema real de los 30 segundos de ordenamiento.

· Revisa los controladores de eventos de tu listview para verificar si estás haciendo algo incorrecto con los items que provoque ese exceso de tiempo en el ordenamiento... y publica el código relevante, de lo contrario dudo mucho que alguien te pueda ayudar, ya que como digo el problema seguramente no sea del comparer (a menos que la lógica del comparer que estés usando sea tan incorrecta como para provocar ese tipo de problema).

Te sugiero reemplazar la lógica de ordenamiento que estés utilizando y probar con el siguiente código fuente extraido de la próxima versión (sin publicar todavía) de mi API ElektroKit:




Ejemplo de uso:
Código
  1. Public Class Form1 : Inherits Form
  2.  
  3.    Friend WithEvents MyListView As New ListView
  4.    Private sorter As New ListViewColumnSorter
  5.  
  6.    Public Sub New()
  7.  
  8.        MyClass.InitializeComponent()
  9.  
  10.        With Me.MyListView
  11.  
  12.            ' Set the sorter, our ListViewColumnSorter.
  13.            .ListViewItemSorter = sorter
  14.  
  15.            ' The initial direction for the sorting.
  16.            .Sorting = SortOrder.Ascending
  17.  
  18.            ' Set the initial sort-modifier.
  19.            sorter.SortModifier = SortModifiers.SortByText
  20.  
  21.            ' Add some columns.
  22.            .Columns.Add("Text").Tag = SortModifiers.SortByText
  23.            .Columns.Add("Numbers").Tag = SortModifiers.SortByNumber
  24.            .Columns.Add("Dates").Tag = SortModifiers.SortByDate
  25.  
  26.            ' Adjust the column sizes.
  27.            For Each col As ColumnHeader In Me.MyListView.Columns
  28.                col.Width = 100
  29.            Next
  30.  
  31.            ' Add some items.
  32.            .Items.Add("hello").SubItems.AddRange({"2", "11/11/2000"})
  33.            .Items.Add("yeehaa!").SubItems.AddRange({"1", "9/9/1999"})
  34.            .Items.Add("El3ktr0").SubItems.AddRange({"100", "21/08/2014"})
  35.            .Items.Add("wow").SubItems.AddRange({"10", "11-11-2000"})
  36.  
  37.            ' Styling things.
  38.            .Dock = DockStyle.Fill
  39.            .View = View.Details
  40.            .FullRowSelect = True
  41.        End With
  42.  
  43.        With Me ' Styling things.
  44.            .Size = New Size(400, 200)
  45.            .FormBorderStyle = Global.System.Windows.Forms.FormBorderStyle.FixedSingle
  46.            .MaximizeBox = False
  47.            .StartPosition = FormStartPosition.CenterScreen
  48.            .Text = "ListViewColumnSorter TestForm"
  49.        End With
  50.  
  51.        Me.Controls.Add(Me.MyListView)
  52.  
  53.    End Sub
  54.  
  55.    ''' ----------------------------------------------------------------------------------------------------
  56.    ''' <summary>
  57.    ''' Handles the <see cref="ListView.ColumnClick"/> event of the <see cref="MyListView"/> control.
  58.    ''' </summary>
  59.    ''' ----------------------------------------------------------------------------------------------------
  60.    Private Sub MyListView_ColumnClick(ByVal sender As Object, ByVal e As ColumnClickEventArgs) _
  61.    Handles MyListView.ColumnClick
  62.  
  63.        Dim lv As ListView = DirectCast(sender, ListView)
  64.  
  65.        ' Dinamycaly sets the sort-modifier to sort the column by text, number, or date.
  66.        sorter.SortModifier = DirectCast(lv.Columns(e.Column).Tag, SortModifiers)
  67.  
  68.        ' Determine whether clicked column is already the column that is being sorted.
  69.        If (e.Column = sorter.ColumnIndex) Then
  70.  
  71.            ' Reverse the current sort direction for this column.
  72.            If (sorter.Order = SortOrder.Ascending) Then
  73.                sorter.Order = SortOrder.Descending
  74.  
  75.            Else
  76.                sorter.Order = SortOrder.Ascending
  77.  
  78.            End If
  79.  
  80.        Else
  81.            ' Set the column number that is to be sorted, default to ascending.
  82.            sorter.ColumnIndex = e.Column
  83.            sorter.Order = SortOrder.Ascending
  84.  
  85.        End If ' e.Column
  86.  
  87.        ' Perform the sort.
  88.        lv.Sort()
  89.  
  90.    End Sub
  91.  
  92. End Class



han pasado pvarios años desde el ultimo post.

Está prohibido revivir temas antiguos, si sigues teniendo ese problema con el listview entonces debes formular tus dudas en un nuevo hilo y si quieres puedes hacer referencia a este u otro hilo poniendo la url para mencionar el contenido/cçodigo del post o contestar a cualquiera de las preguntas que te hice...

Tema cerrado.

Saludos!
« Última modificación: 12 Enero 2016, 22:06 pm por Eleкtro » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines