Results 1 to 11 of 11

Thread: [RESOLVED] Clickable picture box in flowlayoutpanel

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Sep 2010
    Location
    Glogow, Poland
    Posts
    104

    Resolved [RESOLVED] Clickable picture box in flowlayoutpanel

    Hi,

    Quick question... I know I'm lame, but please help me.

    Got this code (I bolded the part that causes a problem):
    Code:
    Public Class Form5
        Dim TheFilePath As String
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim fbd As New FolderBrowserDialog
            If fbd.ShowDialog = Windows.Forms.DialogResult.OK Then
                TheFilePath = fbd.SelectedPath
                Try
                    For Each F As String In System.IO.Directory.GetFiles(fbd.SelectedPath)
                        Dim NewImage As Image = Image.FromFile(F)
                        NewImage = NewImage.GetThumbnailImage(NewImage.Width * 0.5, NewImage.Height * 0.5, AddressOf abort, System.IntPtr.Zero)
                        Dim P As New PictureBox
                        P.SizeMode = PictureBoxSizeMode.AutoSize
                        P.Image = NewImage
                        AddHandler P.Click, AddressOf PictureBox_Click
                        FlowLayoutPanel1.Controls.Add(P)
                        ListBox1.Items.Add(System.IO.Path.GetFileName(F))
                    Next
                Catch ex As Exception
                    
                End Try
    
            End If
    
        End Sub
        Private Function abort() As Boolean
            Return False
        End Function
    
        Private Sub PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            'code for picturebox click
    
    'WHAT DO I ADD HERE TO OPEN THE CLICKED IMAGE?
    
    
        End Sub
    
    End Class
    This has to be easy, but I can't figure out how to make those pictureboxes in flowlayoutpanel clickable. Any example will do - opening it in default picture browser, using it as panel background or using it as a picture for separate picturebox - anything will do - I simply do not know how to get the file name assiciated with the particular picturebox in the flowlayoutpanel.

    Please help me do it.

  2. #2
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Clickable picture box in flowlayoutpanel

    First off, you need to save the name of the file inside the picturebox somehow. M$ gave us this great property called .Tag which you can use for just this purpose.

    Code:
    P.Image = NewImage
    P.Tag = F   '<< Add this filename to the Tag property
    Now you have this, you can extract it during the click event (something like this, off top of me head).

    Code:
    Dim strFileName As String = DirectCast(sender, PictureBox).Tag.ToString
    So, next question, what do you want to open it with?

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Sep 2010
    Location
    Glogow, Poland
    Posts
    104

    Re: Clickable picture box in flowlayoutpanel

    Thanks a lot Grimfort

    This does the job.

    I will be copying the chosen picture to another folder upon single mouse click. I'm pretty sure I will manage as I did that sort of stuff before.

    For a time being I tested it by displaying full file path in a msg box and also by launching it in a default viewer.

    Here is my code (changes bolded):
    Code:
    Public Class Form5
        Dim TheFilePath As String
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim fbd As New FolderBrowserDialog
            If fbd.ShowDialog = Windows.Forms.DialogResult.OK Then
                TheFilePath = fbd.SelectedPath
                Try
                    For Each F As String In System.IO.Directory.GetFiles(fbd.SelectedPath)
                        Dim NewImage As Image = Image.FromFile(F)
                        NewImage = NewImage.GetThumbnailImage(NewImage.Width * 0.5, NewImage.Height * 0.5, AddressOf abort, System.IntPtr.Zero)
                        Dim P As New PictureBox
                        P.SizeMode = PictureBoxSizeMode.AutoSize
                        P.Image = NewImage
                        P.Tag = F
                        AddHandler P.Click, AddressOf PictureBox_Click
                        FlowLayoutPanel1.Controls.Add(P)
                        ListBox1.Items.Add(System.IO.Path.GetFileName(F))
                    Next
                Catch ex As Exception
                    
                End Try
    
            End If
    
        End Sub
        Private Function abort() As Boolean
            Return False
        End Function
    
        Private Sub PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            'code for picturebox click
            
            Dim strFileName As String = DirectCast(sender, PictureBox).Tag.ToString
            MsgBox(strFileName.ToString)
            Process.Start(strFileName)
    
        End Sub
    
    End Class
    I'll play with it more later and resolve the thread if I don't encounter any issues.

    Cheers.

  4. #4
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Clickable picture box in flowlayoutpanel

    Funny, I was actually going to suggest in your other thread that you use a UserControl that consisted of a PictureBox + Label, and then a FlowLayoutPanel which you add them to. Seems you've done similar.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Sep 2010
    Location
    Glogow, Poland
    Posts
    104

    Re: Clickable picture box in flowlayoutpanel

    Thanks for interest ForumAccount – I appreciate that. Google was first on this occasion , but maybe you (or anybody else) will be able to help me with the above code.

    Everything so far works as expected, but(!) if the folder contains files other than images it returns an 'Out of Memory' exception. Is there a way to modify the above code so it will look for specified extensions only (jpg, bmp, png, gif etc) and ignore any other files? It stops processing further files if the error occurs (typically it goes in alphabetical order).

    lets say I have such files in folder:
    aaa.jpg
    bbb.gif
    ccc.zip
    ddd.jpg

    Then it will add only aaa.jpg and bbb.gif to the flowlayoutpanel, throw an exception at ccc.zip and never process ddd.jpg.

    How do I avoid such issue? Any ideas?
    Last edited by marl; Jul 21st, 2011 at 10:36 AM.

  6. #6
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Clickable picture box in flowlayoutpanel

    Inside your loop you are getting every file that is in the directory. You aren't actually checking whether:
    1. The valid has a valid image extension
    2. The file is a valid image

    What you need to do is, inside your loop add some logic that filters out the files you don't want. Then use a Try...Catch block to catch any exceptions from trying to read the file. When you are coding, you should be trying to see what exceptions each method can throw and determining how you can deal with them. For the Image.FromFile method, for example, you see that it can throw 3 different exceptions. You will also see that one of those exceptions is an OutOfMemoryException that occurs when:
    The file does not have a valid image format.
    -or-
    GDI+ does not support the pixel format of the file.
    You will have to use a Try...Catch block because there is no code that you can use that can safely determine whether a file is a valid image without it throwing an exception.

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Sep 2010
    Location
    Glogow, Poland
    Posts
    104

    Re: Clickable picture box in flowlayoutpanel

    Hi ForumAccount,

    Of course I catched the exception. It simply says Out of Memory - this is it.

    I tested it by moving files in the folder around and I came to the conclusion that the error is cause by "file which does not have a valid image format". I put a TXT file into the folder - exception. I remove the TXT from the folder - no exception. Same with other extensions which aren't representing graphics.

    I guess I should use something like this:

    Select Case .........
    Case ".jpg", ".bmp", ".gif", ".png", ".ico"
    ............
    End Select

    I simply don't know the correct syntax and have no idea where exactly should I apply it in the above code.

    Would you be so kind to post some code examples for me to try?

  8. #8
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Clickable picture box in flowlayoutpanel

    You would have been better asking this as a new question, you might get confused. You actually have the right idea. I would suggest a change to the directoryinfo class instead of just directory. Like this:

    Code:
    Dim DirInfo As New IO.DirectoryInfo(fbd.SelectedPath)
    Now when you ask for the files, you can get FileInfo back instead of just filename.

    Code:
    For Each F As FileInfo In DirInfo.GetFiles()
    You can then access stuff like F.Extension

    Code:
    Select Case F.Extension.ToLower
       Case ".jpg", ".bmp", ".png"
             Try   'Notice the try INSIDE the loop, as you do not want to fail at the first problem, but ignore and keep going
                Dim NewImage As Image = Image.FromFile(F.FullName)
                 ....
             Catch ex As Exception
    
             End Try
    End Select

  9. #9
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Clickable picture box in flowlayoutpanel

    You will not be able to create an image of an icon this way. You will have to use the Icon class, an Image is not an Icon.
    Code:
    '//you can use an array of valid extensions to determine which files
    '//actually go through to where you try and create an image from it
    '//this is probably more suited as a class level variable, i've declared
    '//it locally here but you should move it out
    Dim validExtensions = New String() {"tiff", "bmp", "png", "jpg", "jpeg"}
    
    For Each F As String In System.IO.Directory.GetFiles(fbd.SelectedPath)
        Dim extension = IO.Path.GetExtension(F)
    
        '//call ToLower because we don't want case sensitivity
        If Array.IndexOf(validExtensions, extension.ToLower()) > -1 Then
            '//valid extension
            Try
                '//nest the Try inside the For loop, this will cause any problems
                '//to be handled in the Catch block, and the next file to be processed
                Dim NewImage As Image = Image.FromFile(F)
                NewImage = NewImage.GetThumbnailImage(NewImage.Width * 0.5, NewImage.Height * 0.5, _
                                                      AddressOf abort, System.IntPtr.Zero)
                Dim P As New PictureBox
                P.SizeMode = PictureBoxSizeMode.AutoSize
                P.Image = NewImage
                P.Tag = F
                AddHandler P.Click, AddressOf PictureBox_Click
                FlowLayoutPanel1.Controls.Add(P)
                ListBox1.Items.Add(System.IO.Path.GetFileName(F))
            Catch ex As OutOfMemoryException
                '//invalid file here, deal with the exception
            End Try
        End If
        
    Next

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Sep 2010
    Location
    Glogow, Poland
    Posts
    104

    Re: Clickable picture box in flowlayoutpanel

    Thanks for the replies.

    I used examples of code proposed by Grimfort and it solved my problems.

    I did not checked code example pasted by ForumAccount since Grimfort's answer did the job.

    Thank you both (Gimfort and ForumAccount) for your help. Great stuff. I appreciate your input.

    @ ForumAccount - apologies for confusion - I'm not interested in ICO files at all. I only need jpg, png and gif (bmp... hmmm maybe - doubtful).

    Here is my final code (test code as I will use it in something bigger, but this works as expected):

    Code:
    Imports System.IO
    Public Class Form5
        Dim TheFilePath As String
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim fbd As New FolderBrowserDialog
            If fbd.ShowDialog = Windows.Forms.DialogResult.OK Then
                TheFilePath = fbd.SelectedPath
                Try
                    Dim DirInfo As New IO.DirectoryInfo(fbd.SelectedPath)
                    For Each F As FileInfo In DirInfo.GetFiles()
                        Select F.Extension.ToLower
                            Case ".jpg", ".bmp", ".png", ".gif"
                                Try
                                    Dim NewImage As Image = Image.FromFile(F.FullName)
                                    NewImage = NewImage.GetThumbnailImage(NewImage.Width * 0.2, NewImage.Height * 0.2, AddressOf abort, System.IntPtr.Zero)
                                    Dim P As New PictureBox
                                    P.SizeMode = PictureBoxSizeMode.AutoSize
                                    P.Image = NewImage
                                    P.Tag = F.FullName
                                    AddHandler P.Click, AddressOf PictureBox_Click
                                    FlowLayoutPanel1.Controls.Add(P)
                                    ListBox1.Items.Add(System.IO.Path.GetFileName(F.FullName))
                                    'MsgBox(P.Tag.ToString)
                                Catch ex As Exception
                                    MsgBox("Error inside the loop" + vbCrLf + vbCrLf + "description of the error:" + vbCrLf + ex.Message, MsgBoxStyle.Exclamation)
                                End Try
                        End Select
    
                    Next
                Catch ex As Exception
                    MsgBox("Error" + vbCrLf + vbCrLf + "description of the error:" + vbCrLf + ex.Message, MsgBoxStyle.Exclamation)
                End Try
    
            End If
    
        End Sub
        Private Function abort() As Boolean
            Return False
        End Function
    
        Private Sub PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            'code for picturebox click
            Dim strFileName As String = DirectCast(sender, PictureBox).Tag.ToString
            'MsgBox(strFileName.ToString)
            Process.Start(strFileName)
    
        End Sub
    
    End Class
    Please note that there are some unnecessary bits and bobs in the code.

    Notes for other people reading this:

    you need a windows form (in this case named Form5) and a flowlayoutpanel1 in it as well as listbox1 and button1 - obvious isn't it ?

    Now - some tags for search engine, so somebody else could find this thread:
    vb picture browser thumbnail picturebox miniatures picturebox click folder images preview image resize visual basic studio 2010

    Thanks a lot for the input ForumAccount & Grimfort

    I'm marking this thread as RESOLVED

  11. #11
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Clickable picture box in flowlayoutpanel

    Quote Originally Posted by marl View Post
    I used examples of code proposed by Grimfort and it solved my problems.

    I did not checked code example pasted by ForumAccount since Grimfort's answer did the job.

    Thank you both (Gimfort and ForumAccount) for your help. Great stuff. I appreciate your input.
    No probs. ForumAccounts reply was near exactly the same as mine as it happens, either would work.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width