Vamos ao código.
A primeira coisa a ser feita é definir o que você vai precisar ordenar. Neste exemplo irei demonstrar como ordenar Data, números e Texto. Iremos agora declarar nossas variáveis e criar o codigo para receber as mesmas sempre que a nossa classe for chamada. Usaremos a palavra Implements para implementar a Interface IComparer. Interfaces são classes que possuem apenas metodos e não possuem implementação, ou seja, a mesma não possui código apenas chamadas de metodos. A classe que herdar a Inteface terá que implementar o seu método e seguir o modelo de sua chamada.
'IMPLEMENTA A Interface IComparer
Implements IComparer
VERIFICAR ORDEM
Private Coluna As Integer
'VARIAVEL QUE VAI RECEBER O TIPO DE ORDEM
“Descending ou Ascending”
Private OrdemSort As SortOrder
Agora definiremos como iremos receber os valores Coluna e OrdemSort. Neste exemplo, os mesmos serão recebidos junto à chamada da Classe, ou seja, no procedimento Public Sub New.
Public Sub New(ByVal ColunaClique As Integer,ByVal OrdemSort As SortOrder)
Me.OrdemSort = OrdemSort
Nosso código deve ficar assim:
Class CompararItensListview
Implements IComparer
Private Coluna As Integer
Private OrdemSort As SortOrder
Public Sub New(ByVal ColunaClique As _
Integer, ByVal OrdemSort As SortOrder)
Me.OrdemSort = OrdemSort
End Class
O que temos que fazer agora é a função que vai organizar o Listview. O método que iremos implementar da Classe IComparer é a função compare que possui dois parâmetros: o X que representa o item que vai ser comparado; e o Y, o item anterior a este na ordem conforme exemplo abaixo:
Public Function Compare(ByVal x As Object,ByVal y As Object) As Integer _
End Function
Veremos agora como fazer a comparação entre os valores do Listview para estabelecer a ordem dos mesmos. O que faremos agora é uma verificação do tipo de dados da coluna selecionada e sua validação conforme este. Por exemplo, suponhamos que na sua coluna você possui datas. Para fazer esta verificação usaremos a função DateTime.TryParse que é semelhante ao IsDate do antigo VB6.
'PARA UTILIZAR A FUNÇÃO DateTime.TryParse TEMOS QUE DEFINIR UMA DATA VÁLIDA CONFORME EXEMPLO ABAIXO
Dim DataValida As DateTime
ListViewItem).SubItems(Coluna).Text, DataValida) Then
0 – Igual ao item anterior fica onde esta
-1 – É menor sobe para a posição do item anterior
1 – Vai uma posição para frente
Convert.ToDouble – transforma em valor para comparação
String.Compare - compara duas strings
Class CompararItensListview
Implements IComparer
Private Coluna As Integer
Private OrdemSort As SortOrder
Public Sub New(ByVal ColunaClique As Integer, ByVal _
OrdemSort As SortOrder)
Coluna = ColunaClique
Me.OrdemSort = OrdemSort
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) _
As Integer Implements System.Collections.IComparer.Compare
Dim OrdemItem As Integer
Dim DataValida As DateTime
Dim NumeroValido As Double
If DateTime.TryParse(CType(x, ListViewItem).SubItems(Coluna).Text, _
DataValida) Then
If DateTime.TryParse(CType(y, ListViewItem).SubItems(Coluna).Text, _
DataValida) Then
OrdemItem = DateTime.Compare(CType(x, ListViewItem).SubItems _
(Coluna).Text, CType(y, ListViewItem).SubItems(Coluna).Text)
MsgBox(CType(x, ListViewItem).SubItems(Coluna).Text)
MsgBox(CType(y, ListViewItem).SubItems(Coluna).Text)
Else
OrdemItem = -1
End If
ElseIf Double.TryParse(CType(x, ListViewItem).SubItems(Coluna) _
.Text, NumeroValido) Then
If Double.TryParse(CType(y, ListViewItem).SubItems(Coluna).Text _
, NumeroValido) Then
If Convert.ToDouble(CType(x, ListViewItem).SubItems(Coluna).Text) _
= Convert.ToDouble(CType(y, ListViewItem).SubItems(Coluna).Text) Then
OrdemItem = 0
ElseIf Convert.ToDouble(CType(x, ListViewItem).SubItems _
(Coluna).Text) > Convert.ToDouble(CType(y, ListViewItem). _
SubItems(Coluna).Text) Then
OrdemItem = 1
Else
OrdemItem = -1
End If
Else
OrdemItem = -1
End If
Else
If CType(x, ListViewItem).SubItems(Coluna).Text.Trim = "" Then
OrdemItem = 1
Else
OrdemItem = String.Compare(CType(x, ListViewItem). _
SubItems(Coluna).Text, CType(y, ListViewItem).SubItems _
(Coluna).Text)
End If
End If
'INVERTE O RETORNO EM CASO DE ORDEM DECRESCENTE
If OrdemSort = SortOrder.Descending Then
OrdemItem *= -1
End If
Return OrdemItem
End Function
End Class
Vamos ao codigo do formulário insira um Listview no Form criado e coloque o código abaixo:
Dim ColunaSelecionada As Integer = -1
Private Sub ListView1_ColumnClick(ByVal sender As Object, _
ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
'VERIFICA SE CLIQUE É NA MESMA COLUNA
'SE FOR ORDENA DECRESCENTE
If e.Column <> ColunaSelecionada Then
ColunaSelecionada = e.Column
ListView1.Sorting = SortOrder.Ascending
Else
If ListView1.Sorting = SortOrder.Ascending Then
ListView1.Sorting = SortOrder.Descending
Else
ListView1.Sorting = SortOrder.Ascending
End If
End If
'CHAMA METODO QUE IRA ORDENAR O LISTIVEW
ListView1.ListViewItemSorter = New _
CompararItensListview(e.Column, ListView1.Sorting)
End Sub
Para testar insira alguns dados no seu Listview varie as colunas com datas, numeros e texto para ver se funciona abraços e até o proximo.
Baixe o projeto completo escrito no Visual Studio 2008 no link abaixo:
4 comentários:
Olá Amigo, show de bola essa sua classe de ordenação, comecei a usá-la, porém obtive um erro inesperado quando tentava repreencher o listview, um erro com a seguinte mensagem: "InvalidArgument=Value of '1' is not valid for 'index'. Parameter name: index". Aos poucos descobri que o erro era devido ao fato de a sua classe mudar a ordem dos índices do listview e consegui resolver o problema e gostaria de compartolhar a solução com os amigos desenvolvedores:
após clicar nas colunas os índices do listview são mudados, postanto sempre que formos repreenche-lo (usando um "select" após cadastro ou fazendo uma consulta) temos que colocar a ordenação na forma original. Para isso usei o seguinte código que resolveu de cara o meu problema:
"ListView1.Sorting = SortOrder.None"
deixo meu email para qualquer dúvida:
helcio.carmo.ribeiro@hotmail.com
Amigo, obrigado por tudo!
Topico muito bom cara, funcionou perfeitamente na minha aplicação,
Valeu
Preciso de uma ajuda para criar um listview vindo do banco de dados.me manda um emial para eu entrar em contator. mbarroscribeiro@hotmail.com
Postar um comentário