Plantage sur tri dans une listview (VB.NET 2008)

jlfcdvg Messages postés 39 Date d'inscription samedi 19 juillet 2003 Statut Membre Dernière intervention 13 octobre 2013 - 7 sept. 2013 à 07:03
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 - 13 sept. 2013 à 11:28
Bonjour,
J'utilise une listview que j'alimente de façon différente en cliquant sur des boutons radio
ça fonctionne bien mais quand je veux trier en cliquant sur les entêtes de colonnes j'ai des erreurs si ensuite je change de liste avec les boutons radio

J'ai fait différents essais

Quand je trie sur la colonne 1 ça marche
quand je trie sur la colonne 2 j'ai cette erreur

InvalidArgument=La valeur '1' n'est pas valide pour 'index'.
Nom du paramètre : index

Quand je trie sur la colonne 3 j'ai cette erreur
InvalidArgument=La valeur '2' n'est pas valide pour 'index'.
Nom du paramètre : index

J'ai l'impression que c'est un problème d'index de colonnes au niveau de la listview

Voici le code de mon formulaire, si vous pouviez me guider vers une solution ...

Au debug ça s'arrête au niveau de la ligne 30 ( Return String.Compare(CType(x, etc .....)
Merci d'avance

Imports System
Imports System.Data
Imports System.Data.OleDb
Imports Microsoft.VisualBasic

Public Class FilmsIncomplets
    Inherits System.Windows.Forms.Form
    Class ListViewItemComparer
        Implements IComparer
        Private col As Integer
        Private sortOrder As SortOrder

        Public Sub New()
            col = 0
            sortOrder = Windows.Forms.SortOrder.Ascending
        End Sub

        Public Sub New(ByVal column As Integer)
            col = column
            sortOrder = Windows.Forms.SortOrder.Ascending
        End Sub

        Public Sub New(ByVal column As Integer, ByVal s As SortOrder)
            col = column
            sortOrder = s
        End Sub

        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
            If sortOrder = Windows.Forms.SortOrder.Ascending Then
                Return String.Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
            Else
                Return String.Compare(CType(y, ListViewItem).SubItems(col).Text, CType(x, ListViewItem).SubItems(col).Text)
            End If

        End Function

    End Class
    Public Function Init_ListBA()
        ListView.Items.Clear()
        ListView.Columns.Clear()
        Dim MyConnexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=" & _
                     "C:AccessDvdData.mdb")
        Dim Mycommand As OleDbCommand = MyConnexion.CreateCommand()

        Mycommand.CommandText = "SELECT RéfCollectionVidéo,TitreFilm,AnnéeSortie,PrésenceVidéo FROM Vidéo" & _
        " WHERE PrésenceVidéo = False ORDER BY TitreFilm"

        MyConnexion.Open()

        Dim myReader As OleDbDataReader = Mycommand.ExecuteReader()
        ListView.View = View.Details
        With ListView.Columns
            .Add("N°", 45, HorizontalAlignment.Left)
            .Add("Titre du film", 305, HorizontalAlignment.Left)
            .Add("Année", 45, HorizontalAlignment.Left)
        End With


        Do While myReader.Read()
            Dim _MyListViewItem As ListViewItem = ListView.Items.Add(Format(myReader.GetValue(0), "000"))
            With _MyListViewItem
                .SubItems.Add(myReader.GetValue(1).ToString)
                .SubItems.Add(myReader.GetValue(2).ToString)
            End With
        Loop
        myReader.Close()
        MyConnexion.Close()
        Return Nothing
    End Function
    Public Function Init_ListeMusique()
        ListView.Items.Clear()
        ListView.Columns.Clear()
        Dim MyConnexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=" & _
                     "C:AccessDvdData.mdb")
        Dim Mycommand As OleDbCommand = MyConnexion.CreateCommand()

        Mycommand.CommandText = "SELECT RéfCollectionVidéo,TitreFilm,Musique,PrésenceMusiqueFilm FROM Vidéo" & _
                                " WHERE PrésenceMusiqueFilm = False ORDER BY TitreFilm"

        MyConnexion.Open()

        Dim myReader As OleDbDataReader = Mycommand.ExecuteReader()
        ListView.View = View.Details
        With ListView.Columns
            .Add("N°", 45, HorizontalAlignment.Left)
            .Add("Titre du film", 250, HorizontalAlignment.Left)
            .Add("Compositeur", 100, HorizontalAlignment.Left)
        End With


        Do While myReader.Read()
            Dim _MyListViewItem As ListViewItem = ListView.Items.Add(Format(myReader.GetValue(0), "000"))
            With _MyListViewItem
                .SubItems.Add(myReader.GetValue(1).ToString)
                .SubItems.Add(myReader.GetValue(2).ToString)
            End With
        Loop

        myReader.Close()

        MyConnexion.Close()
        Return Nothing
    End Function
    Private Sub FilmsIncomplets_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Init_ListBA()
    End Sub

    Private Sub RadioButtonBA_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadioButtonBA.CheckedChanged
        Init_ListBA()
    End Sub

    Private Sub RadioButtonMusique_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadioButtonMusique.CheckedChanged
        Init_ListeMusique()
    End Sub
    Private Sub ListView_ColumnClick(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView.ColumnClick
        If Me.ListView.Sorting = SortOrder.Ascending Then
            Me.ListView.Sorting = SortOrder.Descending
        Else
            Me.ListView.Sorting = SortOrder.Ascending
        End If
        Me.ListView.ListViewItemSorter = New ListViewItemComparer(e.Column, Me.ListView.Sorting)
    End Sub
End Class



jlfcdvg

4 réponses

NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
7 sept. 2013 à 15:08
Bonjour,

As-tu essayer en pas à pas pour voir quelle était la dimension et la valeur des éléments de la ligne ?
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137
7 sept. 2013 à 16:13
Bonjour,

Essaye cela à la place:

en déclaration:

  'Les colonnes actuellement utilisées pour le tri.
    Private m_SortingColumn As ColumnHeader


Ensuite avec l'evenement ListView1_ColumnClick:

#Region "Trier Listview"
    ' Trier en fonction de la colonne cliquée.
    Private Sub ListView1_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
        'Obtenez la nouvelle colonne de tri.
        Dim new_sorting_column As ColumnHeader = _
            ListView1.Columns(e.Column)

        ' Calculez le nouvel ordre de tri.
        Dim sort_order As System.Windows.Forms.SortOrder
        If m_SortingColumn Is Nothing Then
            ' Nouvelle colonne. Croissant Trier.
            sort_order = SortOrder.Ascending
        Else
            ' Voir si c'est la même colonne.
            If new_sorting_column.Equals(m_SortingColumn) Then
                ' Même colonne. Mettez l'ordre de tri.
                If m_SortingColumn.Text.StartsWith("> ") Then
                    sort_order = SortOrder.Descending
                Else
                    sort_order = SortOrder.Ascending
                End If
            Else
                ' Nouvelle colonne. Croissant Trier.
                sort_order = SortOrder.Ascending
            End If

            ' Supprimer l'indicateur de l'ancien tri.
            m_SortingColumn.Text = m_SortingColumn.Text.Substring(2)
        End If

        'Afficher le nouvel ordre de tri.
        m_SortingColumn = new_sorting_column
        If sort_order = SortOrder.Ascending Then
            m_SortingColumn.Text = "> " & m_SortingColumn.Text
        Else
            m_SortingColumn.Text = "< " & m_SortingColumn.Text
        End If

        ' Créer un comparateur.
        ListView1.ListViewItemSorter = New ListViewComparer(e.Column, sort_order)

        ' Trier.
        ListView1.Sort()
    End Sub

#End Region
#Region "Comparateur"
    'Met en oeuvre un comparateur pour les colonnes de ListView.
    Class ListViewComparer
        Implements IComparer

        Private m_ColumnNumber As Integer
        Private m_SortOrder As SortOrder
        Public Sub New(ByVal column_number As Integer, ByVal sort_order As SortOrder)
            m_ColumnNumber = column_number
            m_SortOrder = sort_order
        End Sub
        'Comparer les articles dans la colonne appropriée 
        'pour les objets x et y.
        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            Dim item_x As ListViewItem = DirectCast(x, ListViewItem)
            Dim item_y As ListViewItem = DirectCast(y, ListViewItem)

            'Obtenez les valeurs sous-élément.
            Dim string_x As String
            If item_x.SubItems.Count <= m_ColumnNumber Then
                string_x = ""
            Else
                string_x = item_x.SubItems(m_ColumnNumber).Text
            End If

            Dim string_y As String
            If item_y.SubItems.Count <= m_ColumnNumber Then
                string_y = ""
            Else
                string_y = item_y.SubItems(m_ColumnNumber).Text
            End If

            ' Les comparer.
            If m_SortOrder = SortOrder.Ascending Then
                If IsNumeric(string_x) And IsNumeric(string_y) Then
                    Return Val(string_x).CompareTo(Val(string_y))
                ElseIf IsDate(string_x) And IsDate(string_y) Then
                    Return DateTime.Parse(string_x).CompareTo(DateTime.Parse(string_y))
                Else
                    Return String.Compare(string_x, string_y)
                End If
            Else
                If IsNumeric(string_x) And IsNumeric(string_y) Then
                    Return Val(string_y).CompareTo(Val(string_x))
                ElseIf IsDate(string_x) And IsDate(string_y) Then
                    Return DateTime.Parse(string_y).CompareTo(DateTime.Parse(string_x))
                Else
                    Return String.Compare(string_y, string_x)
                End If
            End If
        End Function
    End Class
#End Region

0
jlfcdvg Messages postés 39 Date d'inscription samedi 19 juillet 2003 Statut Membre Dernière intervention 13 octobre 2013
13 sept. 2013 à 09:22
Bonjour
Merci pour ce code ça fonctionne impec
Peut'on remplacer les < et > par une petite icône comme dans l'explorer Windows
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137
13 sept. 2013 à 11:28
Je suis content que ce code fonctionne.Je tiens à te rappeler qu'il y a le contrôle DataGridView qui est beaucoup plus adapter pour ce genre de programme. Pour ce que tu me demandes je n'ai pas connaissance de ce genre de chose sur une listView
0
Rejoignez-nous