Reputation: 8435
I am trying to change Image
source dynamically based on the data download using Converters
in Xamarin.Forms
There are total three states of fetching data from the server
1) success when data is downloaded successfully 2) error when data is not downloaded and there is an error 3) when process is idle
for all above cases i am using different icon.
here is my XAMLcode
<Image Source="{Binding CustomerState, Converter={StaticResource SyncConverter}}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Grid.Column="0" HeightRequest="20" Margin="8,12,8,12" />
here is my converter code
public class SyncConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool? syncState = value as bool?;
if (syncState != null) {
if (syncState.Value) return "ic_success";
else return "ic_error";
}
return "ic_idle";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
in above code if CustomeState
is null then display ic_idle
icon and if CuswtomerStat
is true then show success otherwise error.
my view model code
private bool? isCustomerState;
public bool? CustomerState
{
get { return isCustomerState; }
set
{
isCustomerState = value;
OnPropertyChanged("CustomerState");
}
}
but somehow xamarin is throwing error at get { return isCustomerState; }
and the error is
System.NullReferenceException: Object reference not set to an instance of an object.
Upvotes: 1
Views: 4510
Reputation: 57
public class SyncConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool))
return ConvertToImageSource("ic_idle");
return (bool)value? ConvertToImageSource("ic_success"): ConvertToImageSource("ic_error");
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return (bool)value;
}
}
Upvotes: 0
Reputation: 13611
Update: As mentioned by Alessandro in the comments - the return type of instance provided by converter might not be the actual issue in this case. The ImageSourceConverter should handle the conversion from string to ImageSource.
As you are binding to the Source property on the Image which is of type ImageSource - so your converter should also return an instance of ImageSource type.
public class SyncConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value != null){
bool? syncState = value as bool?;
if (syncState != null) {
if (syncState.Value) return ConvertToImageSource("ic_success");
else return ConvertToImageSource("ic_error");
}
}
return ConvertToImageSource("ic_idle");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private ImageSource ConvertToImageSource(string fileName)
{
return Device.OnPlatform(
iOS: ImageSource.FromFile($"Images/{fileName}"),
Android: ImageSource.FromFile(fileName),
WinPhone: ImageSource.FromFile($"Images/{fileName}"));
}
}
You can find more details here: https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/#Image_and_ImageSource
Upvotes: 0
Reputation: 5768
you can try to verify "value" before use it. Something like
public class SyncConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value != null){
bool? syncState = value as bool?;
if (syncState != null) {
if (syncState.Value) return "ic_success";
else return "ic_error";
}
}
return "ic_idle";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 7