简体   繁体   中英

WPF Image: Loaded event not being fired

I have an WPF image and I have subscribed to some events:

<Image Grid.Row="0" 
       Source="{Binding Path=ImageSelected,  NotifyOnTargetUpdated=True, Converter={StaticResource imageToSourceConverter}}" 
       Visibility="{Binding imageVisibility}" 
       RenderTransformOrigin="0,0" 
       SnapsToDevicePixels="True" 
       MouseLeftButtonDown="myImage_MouseLeftButtonDown" 
       MouseLeftButtonUp="myImage_MouseLeftButtonUp" 
       MouseMove="myImage_MouseMove" 
       OverridesDefaultStyle="False"
       TargetUpdated="myImage_TargetUpdated"
       Cursor="Hand"
       RenderOptions.BitmapScalingMode="LowQuality" 
       RenderOptions.EdgeMode="Aliased" 
       Loaded="myImage_Loaded">

I have noticed that all events are fired except the Loaded event and I do not understand why. I do not know if it is conflicting with some other events. Which is the sequence of events fired in an image?

Any ideas why it is happening?

What you are experiencing is the intended behavior for that event.

The Loaded event:

Occurs when the element is laid out, rendered, and ready for interaction.

We are talking about a control event. When the control, not the image you load into it, is laid out, rendered and ready for interaction this event will be fired, once.

This is not the right event, if you are looking for one that "tells" you when the image itself is loaded.

DownloadCompleted

If that's what you need, and the images you display are not locally available, but are downloaded over HTTP, you can use the DownloadCompleted event. It is provided by the BitmapSource class. It would require you to bind your Image control to a BitmapSource, instead of providing and Uri , as I suspect is the case right now.

Custom code

The only alternative I know of is to do this manually, which usually gives you also more flexibility. A sample could be the following (untested code):

private void UpdateImageFromBuffer(byte[] yourBuffer)
{
    ThreadPool.QueueUserWorkItem(delegate {
        try {

            SelectedImageLoaded = false; // Set the notification Property and notify that image is being loaded.

            using (MemoryStream memoryStream = new MemoryStream(yourBuffer)) // Remember to provide the yourBuffer variable.
            {
                var imageSource = new BitmapImage();
                imageSource.BeginInit();
                imageSource.StreamSource = memoryStream;
                imageSource.EndInit();
                ImageSelected = imageSource; // Assign ImageSource to your ImageSelected Property.
            }

        } catch (Exception ex) {
            /* You might want to catch this */
        } finally {
            SelectedImageLoaded = true; // Notify that image has been loaded
        }
    });
}

First of all, move the loading of the image to another thread, it's unlikely you want to do this on the UI thread anyway. Depending on what you need to do with that "image-loaded-notification" you need to adapt the code above.

Let's say you want to update the UI depending on what is happening, say display a progress bar or loading animation. In such a case the code above sets the SelectedImageLoaded Property to the current state of the image. All you need to do is to properly bind your UI control to that Property to get the UI to update (Note: class has to implement INotifyPropertyChanged ).

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM