Question Programmatically populate an ImageList collection with all images in folder

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Hi All,

I am new to the forum and also a person who is legally blind, meaning it is difficult to read huge volumes of text, but am hopeful I can get answers here. My issue is this:

I am writing a WIndows Forms Application (.NET 4.5) and have a Form with the following controls:
_ Form1
_ Button1
_ ImageList1
_ ListView1
_ PictureBox1
_ Textbox1

When the user clicks the button a File folder browser will open allowing the user to choose a folder where a gropu of images (JPEG, PNG, TIFF...) are stored. Once the user selects the folder, I want to populate the ImageList collection with ALL images of tpe JPEG or PNG or TIFF (user selectable too) in the ImageList1.Images collection and then show all of those images in the ListView1 control. Can anyone help me with code to do this?

Thanks.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,553
Location
Sydney, Australia
Programming Experience
10+
You would call Directory.GetFiles to get an array of file paths from a folder with a particular extension, loop through that array and call Image.FromFile to create an Image object for each one and Add the Image to the Images collection of the ImageList.
 

IanRyder

Well-known member
Joined
Sep 9, 2012
Messages
1,130
Location
Healing, NE Lincs, UK
Programming Experience
10+
Hi and welcome to the Forum,

I see I got beat to this again but here is a quick demonstration of using the Directory Class to add a collection of images into an ImageList. You can then assign that ImageList to a ListView and use it as you need. i.e:-

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
  For Each currentFile As String In Directory.GetFiles("d:\temp", "*.jpg")
    ImageList1.Images.Add(Image.FromFile(currentFile))
  Next
 
  Dim myLVI As New ListViewItem
  ListView1.LargeImageList = ImageList1
  With myLVI
    .ImageIndex = 0
    .Text = "Some Information"
  End With
  ListView1.Items.Add(myLVI)
End Sub


I will now leave it for you to expand on this demonstration to accomplish exactly what you need.

Hope that helps.

Cheers,

Ian
 

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Hi Guys,
First of all, thanks for getting back to me. I am now able to populate all of the images of type
JPEG in the ImageList1 component. In my test folder, I have
6 JPEG's. The two problems are:

1. I only get 1 Large Icon and associated file name / path to show up in the
ListView1 control. It also appears to be the last JPEG
in the test folder.

2. My test messagebox shows:
ImageList1.Images.count as 12 but I know there is only 6. and
it shows 1 item in the ListView1 control which is right.

See the code below that is called, once the FolderBrowserDialog returns
the path (Eim DirPath as String) and is passed to the below sub
called "GetImges(ByRef DirPath).


  Private Sub GetImages(ByRef DirPath As String)

        'NOT USED YET
        Dim AllowedExt() As String = {"*.JPG", "*.TIFF", "*.PNG"}

        Dim DirFiles() As String = Directory.GetFiles(DirPath)
        Dim ImgFile As String
        Dim LVItem As New ListViewItem
        Dim DirFile As String = ""
        Dim fCount As Integer = 0

        i = 0

        For Each DirFile In Directory.GetFiles(DirPath, "*.JPG")
            DirFiles(i) = DirFile
            TextBox1.Text &= DirFile & vbCrLf
            fCount += 1
        Next

        'SHOWS HOW MANY JPEG FILES WERE FOUND IN THEABOVE 
        'SEARCH OF THE 'DIRPATH' FOLDER

        TextBox1.Text = "There were " & fCount & " JPEG files in the " & vbCrLf & _
            DirPath & " folder..." & vbCrLf & _
            "_________________________" & vbCrLf & TextBox1.Text

        'FOR EACH JPEG FILE IN THE 'DIRPATH' FOLDER
        'POPULATE THE 'ImageList' COLLECTION

        i = 0

        For Each DirFile In Directory.GetFiles(DirPath, "*.JPG")
            DirFiles(i) = DirFile
            ImageList1.Images.Add(Image.FromFile(DirFiles(i)))
            LVItem.ImageIndex = i
            LVItem.Text = DirFiles(i)
            i += 1
        Next

        ListView1.LargeImageList = ImageList1
        ListView1.Items.Add(LVItem)
        ListView1.Refresh()

        MessageBox.Show("ImageList Count = " & ImageList1.Images.Count & vbCrLf & _
                        "ListView1 Count = " & ListView1.Items.Count & vbCrLf)




    End Sub
 
Last edited by a moderator:

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,553
Location
Sydney, Australia
Programming Experience
10+
Firstly, notice how much easier to read IanRyder's code was than yours? I have now fixed your post but please format code snippets for us in future.

1. You only create and add one ListViewItem. If you want to display every Image then you need to create a new ListViewItem and add it to the ListView each time you create a new Image.

2. Are you perhaps adding the Images in the designer and then in code too? If in doubt, debug. Add a breakpoint at the top of the code (F9) and then, when execution breaks, step through the code line by line (F8 or F10, depending on settings). At each step, you can use the Autos, Locals, Watch and Immediate windows and more to examine the state of the app. You can test the item count at the start of the code and at each step through the code to see where it differs from your expectation.
 

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
Hi Ian,

Thanks. This is what I ended up writing:
 For Each Me.DirFile In Directory.GetFiles(DirPath, "*.JPG")
            DirFiles(i) = DirFile
            ImageList1.Images.Add(Image.FromFile(DirFiles(i)))
            'GRAB ONLY FILENAME PORTION OF FILE-PATH
            STR = Mid(DirFiles(i), Len(DirPath) + 2)
            ListView1.Items.Add(STR, imageIndex:=(i))
            i += 1
        Next

Thanks for the assist.

Tim
 
Last edited by a moderator:

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,553
Location
Sydney, Australia
Programming Experience
10+
Firstly, I have fixed your code formatting yet again. Despite my having asked you to format your code snippets, you posted another one unformatted. Please post all code snippets in formatting tags in future.

Secondly, that code needs a spruce up. To start with, don't use a member variable as a loop control variable. That makes no sense. Next, don't assign the current item to an array in the loop because GetFiles already returns an array, so just use that. Next, don't use string manipulation to get a file name from a file path when you can use the Path class. Finally, if you need a counter then use a For loop, not a For Each loop.
Private Sub PopulateListView(folderPath As String)
    Dim filePaths = Directory.GetFiles(folderPath, "*.jpg")

    For i = 0 To filePaths.GetUpperBound(0)
        Dim filePath = filePaths(i)

        Me.ImageList1.Images.Add(Image.FromFile(filePath))
        Me.ListView1.Items.Add(Path.GetFileName(filePath), i).Tag = filePath
    Next
End Sub
Notice that the full path of each file is assigned to the Tag of the corresponding ListViewItem? That's so that you always have direct access to the full path of the file when you select an item. Maybe you need that, maybe you don't.
 

timcurtin

Member
Joined
Dec 13, 2013
Messages
16
Programming Experience
5-10
"Firstly", as you like to say upon first contact, let me inform you that I did not receive our NOTICE of naughty code pasting infractions. Secondly, I informed all who read my first post that I am legally blind and that means INCASE you did not get the memo, I have trouble reading a screen, even with screen enlargement software. Thirdly, while I appreciate you code suggestions, you might stop to ask yourself, I wonder if there MIGHT be a valid reason for the way this guy wrote his code as is... Perhaps you might ask me if there is a reason next time rather than making an imperical statement that it is "wrong". As a person, I am sure you are an alirght guy / girl, but as a moderator, I have to say that you need to take a class on ADA and at least proper communications with total strangers. And that is saying a lot from a guy like me who is what I refer to as "diplomatically aggressive". I bare you no ill will but you need to hear some truth yourself brother. Ease up on the attack campaign and do your job as a moderator and not a hall monitor please. Otherwise, word will get out and people will start wondering about your psychological profile. I say that last bit with a bit of sarcasm admittedly. But seriously man, stop and think before you go off on a person. Walk in their shoes just for a minute before hitting the REPLY button. That is all I am saying man. I just turned 47 and have been dealing with computers since 1984 and have a patent on some cool technology, but that does not mean I know everything about anyting, but it does mean I , while not so blessed in the eyes department am blessed in the noodles in the head department. A lot more bees with honey approach is what I'm saying.

On a more positive note, I happen to be a subject matter expert via years of US Gov contracting, on Accessibility, I might be able to point out some things to make this site more low vision friendly if you were so interested.

Tim
 
Top Bottom