Trier la Liste d'images automatiquement dans la ListView

Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 - Modifié le 16 janv. 2018 à 19:39
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 - 16 janv. 2018 à 21:40
Bonjour ou Bonsoir,
Le code suivant est une partie de mon programme (et il a une relation avec le poste précédant et je sais, il est loin d'être parfais), j'ai pu le créer grâce à différente source qui se trouve ici (l'une d'elle est celle de cs_Le Pivert, http://codes-sources.commentcamarche.net/source/100589-visionneuse-d-image qui m'a beaucoup aidez, Merci)
Ça consiste à récupérer le chemin d'accès d'une image en cliquant sur un bouton (avec l'aide d'une OpenFileDialog) ou glisser l'image dans la PictureBox (grâce à l'événement DragEnter et l'événement DragDrop)
Les étapes sont les suivantes :
1. Récupérer le chemin d'accès de l'image;
2. Récupérer le chemin d'accès du dossier source a partir de ce dernier ;
3. Récupérer le chemin d'accès de toutes les images qui sont dans le dossier;
4. Afficher dans la ListView qui a deux fonctions d'affichages (avec deux boutons) la liste d'image :
a. Afficher les éléments sous forme de grandes miniatures (Afficher les noms et les miniatures des images grâce à ImageList);
b. Afficher les éléments sous forme détails (Colonnes : Nom, Type d'image, Taille du l'image et chemin d'accès de l'image).
Jusqu'à là tout fonction sans problème, la seule chose qui me dérange c'est que les images ne sont pas trier comme pour le dossier (contrairement à la source de cs_Le Pivert, pourtant si je me trompe pas il y a aucun code dans sa source qui permet de trier les images automatiquement)
Alors ma question est la suivante, comment puis-je faire pour les trier automatiquement
Merci d'avance pour vos réponses
Code
Private Sub ListFiles(ByVal FolderPath As String)
        Dim Noms As String = "" 'Nom de l'image
        Dim FileNames = My.Computer.FileSystem.GetFiles(FolderPath, FileIO.SearchOption.SearchTopLevelOnly, "*.gif", "*.bmp", "*.png", "*.tif", "*.tiff", "*.jpg", "*.jpeg", "*.jpe", "*.jfif", "*.ico")
        For Each FileName As String In FileNames 'Chemin d'accés de l'image
            Noms = System.IO.Path.GetFileNameWithoutNoms(FileName) 'Récupérer le Nom de l'image sans Noms
            Dim Info As New IO.FileInfo(FileName)
            Dim Taille_Image_Octet As Long = info.Length
            Dim Kilo_Octet As Integer = 1024 : Dim Mega_Octet As Integer = 1024 * 1024 : Dim Gega_Octet As Integer = 1024 * 1024 * 1024
            Dim Type_Taille_Image As Integer : Dim Unite_Taille_Image As String
            If Taille_Image_Octet < Mega_Octet And Taille_Image_Octet >= Kilo_Octet Then : Type_Taille_Image = Kilo_Octet : Unite_Taille_Image = " Ko"
            ElseIf Taille_Image_Octet < Gega_Octet And Taille_Image_Octet >= Mega_Octet Then : Type_Taille_Image = Mega_Octet : Unite_Taille_Image = " Mo"
            ElseIf Taille_Image_Octet >= Gega_Octet Then : Type_Taille_Image = Gega_Octet : Unite_Taille_Image = " Go" : End If
            Dim Taille_Image_Finale As String = (Taille_Image_Octet / Type_Taille_Image).ToString("0.00") & Unite_Taille_Image
            Dim Type_Image As String
            If info.Name.Substring(info.Name.LastIndexOf(".")) = ".bmp" Or info.Name.Substring(info.Name.LastIndexOf(".")) = ".dib" Then
                Type_Image = "Image Bitmap"
            ElseIf info.Name.Substring(info.Name.LastIndexOf(".")) = ".gif" Then
                Type_Image = "Image GIF"
            ElseIf info.Name.Substring(info.Name.LastIndexOf(".")) = ".ico" Then
                Type_Image = "Icone" '
            ElseIf info.Name.Substring(info.Name.LastIndexOf(".")) = ".jpg" Or info.Name.Substring(info.Name.LastIndexOf(".")) = ".jpeg" Or info.Name.Substring(info.Name.LastIndexOf(".")) = ".jpe" Or info.Name.Substring(info.Name.LastIndexOf(".")) = ".jfif" Then
                Type_Image = "Image JPEG"
            ElseIf info.Name.Substring(info.Name.LastIndexOf(".")) = ".png" Then
                Type_Image = "Image PNG"
            ElseIf info.Name.Substring(info.Name.LastIndexOf(".")) = ".tif" Or info.Name.Substring(info.Name.LastIndexOf(".")) = ".tiff" Then
                Type_Image = "Image TIFF"
            End If
            ImageList1.Images.Add(Bitmap.FromFile(FileName))
            ListView1.Items.Add(New ListViewItem({Noms, Type_Image, Taille_Image_Finale, FileName}, a))
            a = a + 1
        Next
    End Sub
'Récupérer l'image
    Private Sub ButtonImage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonImage.Click
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            TextBox1.Text = OpenFileDialog1.FileName 'Afficher le chemin d'accés de l'image récupérer avec l'OpenFileDialog1 dans la TexteBox1
            chemin = TextBox1.Text
            Using monstream As New IO.FileStream(chemin, IO.FileMode.Open, FileAccess.Read)
                PictureBox1.Image = Image.FromStream(monstream)
                img = Image.FromStream(monstream)
            End Using
            Chemin_dossier_source = System.IO.Path.GetDirectoryName(OpenFileDialog1.FileName)
            Label44.Text = img.Width.ToString & " x " & img.Height.ToString 'Dimmension en pixel de l'image
            ListFiles(Chemin_dossier_source)     'Dossiers()
            For i As Integer = 0 To ListView1.Items.Count - 1
                If ListView1.Items(i).SubItems(3).Text.Contains(TextBox1.Text) Then
                    ListView1.Items(i).Selected = True
                    Label41.Text = System.IO.Path.GetFileName(ListView1.Items(i).SubItems(3).Text)
                    Label9.Text = ListView1.Items(i).SubItems(2).Text
                    Label42.Text = ListView1.Items(i).SubItems(3).Text
                    Fichier_Choisi = ListView1.Items(i).SubItems(3).Text
                    ligne = CInt(ListView1.SelectedIndices(0).ToString())
                Else
                End If
            Next
            Fichier_selectionner = ListView1.Items(ligne).SubItems(3).Text
        Else
        End If 
    End Sub

2 réponses

Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
16 janv. 2018 à 19:53
Bonsoir
une façon de faire, en te forçant un peu à utiliser les objets (paradigme de VB.net...) serait de te créer un objet mesImages, avec toutes les infos qui t'intéressent.

Tu stockes chacune dans une List(of), que tu tries soit avec la méthode Sort (il faut apprendre à la classe à comparer 2 instances en implémentant Icomparable), soit en utilisant une requête Linq SortBy.

Ensuite, il ne te reste qu'à afficher les contenu de la liste dans ta listeview.

Je te poste des exemples par la suite
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
16 janv. 2018 à 21:40
La classe
Imports System
Imports System.Collections.Generic
Imports System.IO


Friend Class MesImages
    Implements IComparable(Of MesImages)
    Private cheminComplet As String

    Public Sub New(ByVal FileName As String)
        Dim extension As String = Path.GetExtension(FileName).ToUpper().Replace(".", "")
        Select Case extension ' c'est un peu mieux qu'une cascade de if
            Case "PNG", "GIF", "TIFF", "JPEG"
                TypeImage = "Image " & extension

            Case "BMP", "DIB"
                TypeImage = "Image Bitmap"

            Case "ICO"
                TypeImage = "Icone"

            Case "JPG", "JPE", "JFIF"
                TypeImage = "Image JPEG"

            Case "TIF"
                TypeImage = "Image TIFF"

            Case Else
                TypeImage = "Pas une image"
                Return
        End Select


        cheminComplet = FileName
        Dim info As New FileInfo(FileName)
        Taille = info.Length

        'une autre façon de calculer la taille, pour l'exemple
        Dim unites() As String = {"Ko", "Mo", "Go", "To"}
        Dim indexUnite As Integer = 0
        Dim tailleReduite As Double
        Do
            indexUnite += 1
            tailleReduite = Taille / Math.Pow(1024, indexUnite)
        Loop While tailleReduite > 1024
        TailleTexte = String.Format("{0:n1} {1}", tailleReduite, unites(indexUnite - 1))

    End Sub

    Public ReadOnly Property NomImage As String
        Get
            Return Path.GetFileName(cheminComplet)
        End Get
    End Property

    Public ReadOnly Property Repertoire As String
        Get
            Return Path.GetDirectoryName(cheminComplet)
        End Get
    End Property

    Public ReadOnly Property LeCheminComplet As String
        Get
            Return cheminComplet
        End Get
    End Property

    Private privateTaille As Long
    Public Property Taille() As Long
        Get
            Return privateTaille
        End Get
        Private Set(ByVal value As Long)
            privateTaille = value
        End Set
    End Property

    Private privateTailleTexte As String
    Public Property TailleTexte() As String
        Get
            Return privateTailleTexte
        End Get
        Private Set(ByVal value As String)
            privateTailleTexte = value
        End Set
    End Property

    Public Property TypeImage() As String

    Public Overrides Function ToString() As String
        Return NomImage & ", " & TailleTexte
    End Function


    ''' <summary>
    ''' Implémentation de Icomparable, par rapport à la taille
    ''' </summary>
    ''' <param name="autre">Instance à comparer</param>
    ''' <returns></returns>
    Public Function CompareTo(ByVal autre As MesImages) As Integer Implements IComparable(Of MesImages).CompareTo
        Return Taille.CompareTo(autre.Taille)
    End Function

    ''' <summary>
    ''' Pour l'exemple, je te montre cette méthode de classe qui liste les images d'un répertoire
    ''' </summary>
    ''' <param name="FileName"></param>
    ''' <returns></returns>
    Public Shared Function ChargeRepertoire(ByVal FileName As String) As List(Of MesImages)
        Dim resultat As New List(Of MesImages)()

        Dim repertoire As String = FileName
        If Path.HasExtension(FileName) Then
            repertoire = Path.GetDirectoryName(repertoire)
        End If

        For Each fichier As String In Directory.GetFiles(repertoire)
            Dim uneImage As New MesImages(fichier)
            If uneImage.TypeImage <> "Pas une image" Then
                resultat.Add(uneImage)
            End If
        Next fichier

        Return resultat
    End Function
End Class


Charger un répertoire et les images trier
        Dim images As List(Of MesImages) = MesImages.ChargeRepertoire("\\VBOXSVR\Partage\Test\Fichier.txt")
        'tri par taille, via Icomparable
        images.Sort()
        'dans l'autre sens
        images.Reverse()

        'tri par nom, via une requete Linq
        images = images.OrderBy(Function(x) x.NomImage).ToList()
        'dans l'autre sens
        images = images.OrderByDescending(Function(x) x.NomImage).ToList()


Et pour afficher, j'ai juste repris ce que tu faisais
        For Each image As MesImages In images
            ImageList1.Images.Add(Bitmap.FromFile(image.LeCheminComplet))
            ListView1.Items.Add(New ListViewItem({image.NomImage, image.TypeImage, image.TailleTexte, image.LeCheminComplet}, a))
            a = a + 1
        Next


J'ai fait ça vite fait, mais mon test a réussi.
0
Rejoignez-nous