Eddie Eddie - 2 months ago 15
C# Question

Image not being displayed in Windows 8.1 Store application

I have a Windows 8.1 Store application and in one of the views I need to display an image. I've done this a million times in WPF desktop application, so it should be easy to do and yet my image is not displayed. I get this image from the repository as a byte array. I checked and I have all the bytes in my ViewModel at the time my view is displayed. Yet, I don't see it. This is the first time I actually try to display an image in a Windows 8.1 Store application, so I wonder if things are done differently.

Here is my XAML code:

<Border Grid.Column="2" BorderBrush="White" BorderThickness="5" Margin="2">
<Image Source="{Binding ImageBuffer}" AutomationProperties.Name="{Binding CompanyName}"
Width="280" Height="190" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>


The code behind contains an "ImageBuffer" public property that, like I said, is properly initialized with all the bytes of the image.

private byte[] _imageBuffer;
public byte[] ImageBuffer
{
get { return _imageBuffer; }
set { Set(() => ImageBuffer, ref _imageBuffer, value); }
}


I use MVVM Light Toolkit for my project.

Any suggestions?

Thanks,
Eddie

Answer

Apparently there is no automatic type conversion from byte[] to ImageSource in WinRT (as it is in WPF). You should have seen an error message in the Output Window in Visual Studio like

Error: Converter failed to convert value of type 'Windows.Foundation.IReferenceArray`1' to type 'ImageSource'; ...

So you should use a Binding Converter like this:

using System;
using System.IO;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media.Imaging;
...

public class ImageConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, string language)
    {
        var bitmap = new BitmapImage();
        var buffer = value as byte[];

        if (buffer != null)
        {
            using (var stream = new InMemoryRandomAccessStream())
            {
                stream.AsStreamForWrite().Write(buffer, 0, buffer.Length);
                stream.Seek(0);
                bitmap.SetSource(stream);
            }
        }

        return bitmap;
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, string language)
    {
        throw new NotSupportedException();
    }
}

Then use it in the Image.Source Binding like this:

<Page.Resources>
    <local:ImageConverter x:Key="ImageConverter"/>
</Page.Resources>
...
<Image Source="{Binding ImageBuffer, Converter={StaticResource ImageConverter}}" ... />
Comments