Reputation: 31
I'm currently getting started with Xamarin.Forms. I have a ListView on my page, that I bind to my ViewModel. The ItemTemplate is of the type 'ImageCell'
There's no problem with binding the Text and Detail properties of the cell. However, I can't manage to bind the 'ImageSourceProperty'. This is imagesource is generated using a byte[] (My images are blobs in a SQLite database)
I was wondering if anyone knew how to solve this problem (or another way to bind a byte[]-image to a listview-item)
Here's some sourcecode:
var model = Graanziekten.Select(g => new OnkruidViewModel
{
Id = g.Id, Naam = g.Naam, Omschrijving = g.Omschrijving, Afbeelding = g.BitmapThumbnail
}).ToList();
var cell = new DataTemplate(typeof(ImageCell));
cell.SetBinding(TextCell.TextProperty, "Naam");
cell.SetBinding(TextCell.DetailProperty, "Omschrijving");
cell.SetBinding(ImageCell.ImageSourceProperty, "Afbeelding");
var listview = new ListView
{
ItemsSource = model,
ItemTemplate = cell
};
the 'BitmapThumbnail' property is defined as:
public ImageSource BitmapThumbnail
{
get
{
//AfbeeldingSmall is a byte[]
return ImageSource.FromStream(() => new MemoryStream(Afbeeldingen.First().AfbeeldingSmall));
}
}
If I use a dummy image (from a uri) it works fine. But if I use the code shown above, the contentpage isn't even rendered at all (empty black screen).
At first I thought the problem might have something to do with the fact the byte[] is fetched from the property dynamically, but the same effect occurs when I fetch all the necessary byte[]'s.
Also, when I add a single image to my contentpage, using the same method it DOES work. Just not in the listview.
I'm trying to do this on WinPhone8 (Although I don't think the platform matters)
Thanks in advance.
Upvotes: 3
Views: 4636
Reputation: 1268
Have you tried binding it to your List directly? Instead of loading that model-object.
var cell = new DataTemplate(typeof(ImageCell));
cell.SetBinding(ImageCell.ImageSourceProperty, "Afbeelding");
cell.SetBinding(TextCell.TextProperty, "Naam");
cell.SetBinding(TextCell.DetailProperty, "Omschrijving");
var listview = new ListView
{
ItemsSource = Graanziekten,
ItemTemplate = cell
};
You can also leave the Image property to this:
public ImageSource BitmapThumbnail
{
get
{
return Afbeeldingen.First().AfbeeldingSmall;
}
}
And use a Converter along with it:
public class ByteArrayToImageConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
byte[] imageAsBytes = (byte[])value;
return ImageSource.FromStream(() => new MemoryStream(imageAsBytes);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
If you'll use the converter, you'll need to change your SetBinding to:
cell.SetBinding(ImageCell.ImageSourceProperty, "Afbeelding", BindingMode.OneWay, new ByteArrayToImageConverter());
EDIT: Your SetBinding(TextCell) should be SetBinding(ImageCell). Can you also try building the datatemplate like this? It shouldn't make a difference but I'm getting out of ideas:
var listview = new ListView
{
ItemsSource = Graanziekten,
ItemTemplate = new DataTemplate(() =>
{
ImageCell imageCell = new ImageCell();
imageCell.SetBinding(ImageCell.ImageSourceProperty, new Binding("Afbeelding", BindingMode.OneWay, new ByteArrayToImageConverter()));
imageCell.SetBinding(ImageCell.TextProperty, "Naam");
imageCell.SetBinding(ImageCell.DetailProperty, "Omschrijving");
return imageCell;
};
};
instead of
var listview = new ListView
{
ItemsSource = Graanziekten,
ItemTemplate = cell
};
Upvotes: 0