简体   繁体   中英

replace image using converters in Xamarin.Forms

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; } get { return isCustomerState; } and the error is

System.NullReferenceException: Object reference not set to an instance of an object.

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();
        }
    }

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

  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;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM