Picturebox ImageLocation Loading

Zexor

Well-known member
Joined
Nov 28, 2008
Messages
520
Programming Experience
3-5
I have a bunch of pictureboxes and i set all their .imagelocation to Urls. So the images will load when it is in view when i scroll to them. Can i trigger a specific picturebox to load the image before its in view? Do i just do a .LoadAsync(.imagelocation) ? Or is there a command to trigger the loading. Also can you check if the picturebox is loading something?

I am trying to preload the picturebox when i am almost scrolled to it.

What happen if you call .LoadAsync on a picturebox that is already loading something?

Right now i am just calling the picturebox.loadasync(picturebox.imagelocation) if picturebox.image is nothing
 
Last edited:
Picturebox load progressively

can picturebox be load progressively like how it does in a browser?
 
remove picturebox while its loading

What can i do if i want to dispose a picturebox while its still loading? I tried disposing it and it get stuck in the picturebox LoadProgressChanged infinitely.
 
If you have already set the ImageLocation then you call LoadAsync without any argument. I don't know what happens if you call LoadAsync when the Image is being or has been loaded but I know an easy way to find out. My guess is that it will be reloaded. To avoid that, you could handle the LoadProgressChanged and LoadCompleted events of each PictureBox to maintain a status for each one. In fact, you could create a custom PictureBox control that incorporated that functionality:
Imports System.ComponentModel

Public Class PictureBoxEx
    Inherits PictureBox

    Private _asyncImageStatus As AsyncImageStatus = AsyncImageStatus.NotLoaded


    Public Property AsyncImageStatus As AsyncImageStatus
        Get
            Return _asyncImageStatus
        End Get
        Private Set(value As AsyncImageStatus)
            Dim oldValue = _asyncImageStatus

            _asyncImageStatus = value

            If oldValue <> value Then
                OnAsyncImageStatusChanged(EventArgs.Empty)
            End If
        End Set
    End Property


    Public Event AsyncImageStatusChanged As EventHandler


    Public Sub ResetAsyncImageStatus()
        AsyncImageStatus = AsyncImageStatus.NotLoaded
    End Sub

    Protected Overridable Sub OnAsyncImageStatusChanged(e As EventArgs)
        RaiseEvent AsyncImageStatusChanged(Me, e)
    End Sub

    Protected Overrides Sub OnLoadProgressChanged(e As ProgressChangedEventArgs)
        AsyncImageStatus = AsyncImageStatus.Loading

        MyBase.OnLoadProgressChanged(e)
    End Sub

    Protected Overrides Sub OnLoadCompleted(e As AsyncCompletedEventArgs)
        AsyncImageStatus = AsyncImageStatus.Loaded

        MyBase.OnLoadCompleted(e)
    End Sub

End Class


Public Enum AsyncImageStatus
    NotLoaded
    Loading
    Loaded
End Enum
Now you can just do something like:
If myPictureBox.AsyncImageStatus = AsyncImageStatus.NotLoaded Then
    myPictureBox.LoadAsync()
End If
 
Last edited:
How many times have I told you to read the documentation and yet you still don't bother. If you had read the relevant PictureBox documentation then you'd know that you can call CancelAsync to stop the asynchronous download. Then it will be safe to dispose the PictureBox. Please make this the last time that you take the lazy option.
 
I did try cancelasync before asking. After i disposed the picturebox and Remaking another one then load another image. All the box before big red X. I can set the imagelocation, but it just wont load anymore. When i try to do LoadAsync, it just say parameter is not valid. The picturebox.image is nothing, but all its value say parameter is not valid.
 
If you tried something and it didn't work then you should have explained that. There's no reason that what you do to one PictureBox should have any effect on any other. Most likely you did something wrong but we can't know if or what because we don't know what you did.
 
does it has anything to do with the image not loading with loadasync but by setting the imagelocation? i notice it seems to work fine if i wait for the images that was loading by setting imagelocation to be done first before i dispose.
 
did the 2 posts got merged? Does CancelAsync work for images load with .imagelocation? It seems to keep on loading even if i call CancelAsync. I think thats the problem. Clearing the imagelocation seems to help. I dont know if its really true.
 
Last edited:
I just did a bit of testing to make sure that I was clear on what was happening because I haven't really done this stuff myself.

1. If you want to load the Image asynchronously then you must set WaitOnLoad to False.
2. If you set the ImageLocation and WaitOnLoad is True then the Image will load synchronously immediately, whether the PictureBox is visible or not.
3. If you set the ImageLocation while the PictureBox is visible (Visible is True and at least part of the PictureBox is not obscured by the form or other controls) and WaitOnLoad is False then the Image will load asynchronously immediately.
4. If you set the ImageLocation while the PictureBox is hidden (Visible is False or the entire PictureBox is outside the visible area of its parent and/or obscured by other controls) and WaitOnLoad is False then the Image will not load immediately.
5. If the ImageLoacation is set but the Image hasn't loaded because the PictureBox is not visible, making the PictureBox visible or calling LoadAsync will load the Image asynchronously.
6. If the Image is loading asynchronously, whether implicitly or by an explicit call to LoadAsync, the LoadProgressChanged and LoadCompleted events will be raised.
7. If the Image is loading asynchronously, whether implicitly or by an explicit call to LoadAsync, calling CancelAsync will stop the Image loading. The LoadCompleted event will still be raised with e.Cancelled set to True.
 
on the PictureBoxEx i notice the asyncImageStatus only change after OnLoadProgressChanged is triggered. What if the picturebox.loadasync is called the 2nd time before there is a progresschange? I see the picture box load again after the image is already loaded.
 
on the PictureBoxEx i notice the asyncImageStatus only change after OnLoadProgressChanged is triggered. What if the picturebox.loadasync is called the 2nd time before there is a progresschange? I see the picture box load again after the image is already loaded.
There's no way that's obvious to me to handle that with the existing members of the PictureBox class, although I haven't researched it in depth. One way that does come to mind is to shadow the LoadAsync method like this:
Public Shadows Sub LoadAsync()
    'Don't do anything if loading is in progress.
    If AsyncImageStatus <> AsyncImageStatus.Loading Then
        If AsyncImageStatus = AsyncImageStatus.NotLoaded Then
            'Just in case loading has started but the LoadProgressChanged event hasn't been raised yet.
            CancelAsync()
        End If

        MyBase.LoadAsync()
    End If
End Sub

Public Shadows Sub LoadAsync(url As String)
    'Don't do anything if loading the same image is in progress.
    If AsyncImageStatus <> AsyncImageStatus.Loading OrElse url <> ImageLocation Then
        'Just in case loading has started but the LoadProgressChanged event hasn't been raised yet.
        CancelAsync()

        MyBase.LoadAsync(url)
    End If
End Sub
Shadowing should generally be avoided if possible but, in this case, it seems to be required.

If an async load is in progress but the AsyncImageStatus has not yet been changed from NotLoaded then that load will be cancelled and another load started. If an async load is in progress and the AsyncImageStatus has been changed to Loading then nothing happens unless the URL of the image is changing. If an async load has already completed then a new one is started.
 
Why cant the AsyncImageStatus be changed right when the LoadAsync is called? I was doing it before with a variable call Loading on each picturebox that is set before the LoadAsync was called.
 
Back
Top