WP81 binding an image fails, setting local fallback image loses original binding

91 Views Asked by At

I am binding the ImageSource of an ImageBrush on Windows Phone 8.1 (RT not silverlight) to a remote uri, and have a handler when the image fails to show a default image:

<ImageBrush Stretch="UniformToFill" ImageSource="{Binding MyBackgroundUrl}" ImageFailed="ImageBrush_ImageFailed"/>

in the code behind I update the image source property to set it to a local image:

    protected void ImageBrush_ImageFailed(object sender, ExceptionRoutedEventArgs e)
    {
            var img = sender as ImageBrush;
            if (img == null) return;

            var uri = new BitmapImage(new Uri("ms-appx:///Assets/App/MyDefaultBackground.jpg"));
            img.ImageSource = uri;
    }

this works GREAT, however by doing this, I am losing the original binding, so that if I reload the same screen with a DIFFERENT binding value, it doesn't re-bind.

This makes sense given what I'm doing, so in that case my question is what did I do wrong and how can I correctly setup a fallback image while allowing the image to re-bind itself when it reloads?

1

There are 1 best solutions below

3
On

Of course you are. You are overwriting the binding. You have to set the property like this:

void ImageBrush_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
    var img = sender as ImageBrush;
    if (img == null) return;

    var uri = new BitmapImage(new Uri("ms-appx:///Assets/App/MyDefaultBackground.jpg"));
    var vm = img.DataContext as MainPageViewModel;
    vm.MyBackgroundUrl = uri;
}

If you don't like that, then you can have two images. One on top of the other and set its visibility based on failure. Something like this pseudo code:

var img = new Image();
// you would not new it up here, you would ref your control.
img.ImageOpened += (s, e) => OverlayImage.Visibility = Visibility.Collapsed;
img.ImageFailed += (s, e) => OverlayImage.Visibility = Visibility.Collapsed;

Make sense to you?

I just noticed you are talking about an image brush and not an image. The logic should be the same, but instead of an overlay it might need to be an underlay. Also, because it is an underlay, you might not need to toggle its visibility since the successful image brush will occlude the underlay. Might be even easier in your case.

Best of luck!