Reputation: 468
I have a list of enum called TransportModeType binded to a Listview with a converter in the datatemplate. The ViewModel looks like this
public class TransportTypeViewMode:ViewModelBase{
public TransportTypeViewMode()
{
TransportTypes= new List<TransportTypeEnum>();
TransportTypes.add(TransportTypeEnum.Car);
TransportTypes.add(TransportTypeEnum.Bus);
TransportTypes.add(TransportTypeEnum.Plane);
}
List<TransportTypeEnum> TransportTypes{get;set;}}
The ListView looks like this
<ListView ItemsSource="{Binding TransportModeTypes}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView>
<Image Source="{Binding Converter={StaticResource ListToImageConverter}}" Aspect="AspectFit"/>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
and my converter called ListToImageConverter looks like this
public class TransportModeEnumToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var transporttModeType = (TransportModeTypeEnum) value;
string imagePath = String.Empty;
switch (transporttModeType)
{
case TransportModeTypeEnum.Bus:
imagePath = "bus.png";
break;
case TransportModeTypeEnum.Train:
imagePath = "train.png";
break;
case TransportModeTypeEnum.Car:
imagePath = "car.png";
break;
case TransportModeTypeEnum.Plane:
imagePath = "plane.png";
break;
default:
throw new ArgumentOutOfRangeException();
}
imagePath = "Common.Images." + imagePath;
var imgResc= ImageSource.FromResource(imagePath);
return imgResc;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
the converter throws an exception that the Value is null.. what am i missing in my binding
Upvotes: 1
Views: 2602
Reputation: 3276
EDIT:
you firstly need to convert your enums to strings, as enums are not a valid itemsource for a listview. So you would need to use the converter for this too.
ViewModel:
public class TransportTypeViewMode : ViewModelBase
{
public TransportTypeViewMode()
{
TransportTypes= new List<TransportTypeEnum>();
TransportTypes.add(TransportTypeEnum.Car);
TransportTypes.add(TransportTypeEnum.Bus);
TransportTypes.add(TransportTypeEnum.Plane);
}
Public List<TransportTypeEnum> TransportTypes{get;set;}}
}
Your enum to string converter:
public class TransportModeEnumToString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var transporttModeType = (TransportModeTypeEnum) value;
string transportName = String.Empty;
switch (transporttModeType)
{
case TransportModeTypeEnum.Bus:
transportName = "bus";
break;
case TransportModeTypeEnum.Train:
transportName = "train";
break;
case TransportModeTypeEnum.Car:
transportName = "car";
break;
case TransportModeTypeEnum.Plane:
transportName = "plane";
break;
default:
throw new ArgumentOutOfRangeException();
}
return transportName;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Your string to imagesource conveter:
public class StringToImagesourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string transporttModeType = (string)value;
string imagePath = String.Empty;
switch (transporttModeType)
{
case "bus":
break;
case TransportModeTypeEnum.Train:
imagePath = "train.png";
break;
case "car":
imagePath = "car.png";
break;
case "plane":
imagePath = "plane.png";
break;
default:
throw new ArgumentOutOfRangeException();
}
imagePath = "Common.Images." + imagePath;
var imgResc= ImageSource.FromResource(imagePath);
return imgResc;
}
}
and your xaml should be something like:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:c="location of your converter classes"
>
<ContentPage.Resources>
<c:EnumToStringConverter x:Key="enumtostring" />
<c:StringToImagesourceConverter x:Key="stringtoimagesource" />
</ContentPage.Resources>
<ContentPage.Content>
<ListView ItemsSource="{Binding TransportModeTypes Converter={StaticResource EnumToStringConverter}}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView>
<Image Source="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource StringToImagesourceConverter}}" Aspect="AspectFit"/>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
Upvotes: 2
Reputation: 34013
Just add a null check and return an empty string or something appropriate.
When the binding is done it gets initialized sometimes with a null value. You can probably safely ignore it. So edit you code something like this:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return String.Empty;
var transporttModeType = (TransportModeTypeEnum) value;
string imagePath = String.Empty;
...
In addition, Jason remarked in the comments that you seem to be missing the path you are binding to here:
<Image Source="{Binding YourProperty, Converter={StaticResource ListToImageConverter}}" Aspect="AspectFit"/>
Notice how I added YourProperty
, which seemed to be missing. Of course, replace it by the name of an actual property in your object.
Upvotes: 0