Xamarin.forms binds listview-imagecell imagesource to byte []
I am currently getting started with Xamarin.Forms. I have a ListView in my page that I am linking to my ViewModel. ItemTemplate is of type "ImageCell"
No problem binding Text and Detail properties to a cell. However, I am unable to bind the "ImageSourceProperty". This image source is generated using byte [] (My images are blocks in SQLite database)
I was wondering if anyone knows how to solve this problem (or another way to bind byte [] - image to listview element)
Here's some source code:
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 uri) it works fine. But if I use the code shown above, the content page is not even displayed at all (blank black screen).
At first I thought the problem might have something to do with the [] byte being retrieved from the property dynamically, but the same effect occurs when I retrieve all the [] bytes needed.
Also, when I add one image to my content page using the same method, it works. Just not on the list.
I'm trying to do this on WinPhone8 (although I don't think the platform matters)
Thanks in advance.
source to share
Have you tried linking it directly to your list? Instead of loading this 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 like this:
public ImageSource BitmapThumbnail
{
get
{
return Afbeeldingen.First().AfbeeldingSmall;
}
}
And use the 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 will be using a converter, you will need to change your SetBinding to:
cell.SetBinding(ImageCell.ImageSourceProperty, "Afbeelding", BindingMode.OneWay, new ByteArrayToImageConverter());
EDIT : Your SetBinding (TextCell) must be SetBinding (ImageCell). Can you also try to create a data template like this? It shouldn't matter, but I get 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
var listview = new ListView
{
ItemsSource = Graanziekten,
ItemTemplate = cell
};
source to share