Search code examples
wpfsql-server-cememorystreamvalueconverter

Why do these two methods of loading images from SQL CE into a WPF Image produce different results?


In a ValueConverter, I was trying to convert a System.Data.Linq.Binary (SQL CE image) to a BitmapImage. This method works (image is show correctly on the form):

public object Convert(object value, Type targetType, object parameter, 
                                                     CultureInfo culture) {
    Binary binary = value as Binary;
    if (binary != null) {
        BitmapImage bitmap = new BitmapImage();
        bitmap.BeginInit();
        bitmap.StreamSource = new MemoryStream(binary.ToArray());
        bitmap.EndInit();
        return bitmap;
    }
    return null;
}

This method does NOT work (but no exception is thrown, strangely):

public object Convert(object value, Type targetType, object parameter, 
                                                     CultureInfo culture) {
    Binary binary = value as Binary;
    if (binary != null) {
        using (var stream = new MemoryStream(binary.ToArray())) {
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.StreamSource = stream;
            bitmap.EndInit();
            return bitmap;
        }
    }
    return null;
}

Good programming practice states that you should dispose of any streams you create... so I'm confused why the second method doesn't work, but the first does. Any insights?


Solution

  • Try this instead:

    public object Convert(object value, Type targetType, object parameter, 
                                                         CultureInfo culture) {
        Binary binary = value as Binary;
        if (binary != null) {
            using (var stream = new MemoryStream(binary.ToArray())) {
                BitmapImage bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad; 
                bitmap.StreamSource = stream;
                bitmap.EndInit();
                bitmap.Freeze(); 
                return bitmap;
            }
        }
        return null;
    }
    

    In your non-working version, your using block means the stream is closed before the image is actually decoded.