Ffimageloading: Get error when I binde HexColor of Tint transformation

Created on 14 Feb 2017  路  13Comments  路  Source: luberda-molinet/FFImageLoading

Hi,
I use ffimageloading in the listView with a TintTransformation, so The binding works fine for image source but for HexColor I get error for missing property. I'v defined a string property for HexColor but It dosn't accept such property:

` FlowColumnMinWidth="60" FlowTappedBackgroundColor="Blue" FlowTappedBackgroundDelay="50" FlowItemsSource="{Binding Items}" x:Name="listView">

<flv:FlowListView.FlowColumnTemplate>
  <DataTemplate>
    <Grid Padding="3">
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>

      <ffimageloading:CachedImage x:Name="selectIcon" WidthRequest="50" HeightRequest="50" DownsampleToViewSize="true"
                                  Source = "{Binding IconPath, Converter={StaticResource ImageSourceConverter}}">
        <ffimageloading:CachedImage.Transformations>
          <fftransformations:TintTransformation HexColor="{Binding HexColor}" EnableSolidColor="true"/>
        </ffimageloading:CachedImage.Transformations>
      </ffimageloading:CachedImage>

    </Grid>
  </DataTemplate>
</flv:FlowListView.FlowColumnTemplate>

My model is:
public class Icons { public string IconPath { get; set; } public string HexColor { get; set; } }

any idea? Thanks

question

Most helpful comment

Oh HexColor is not defined as a bindable property.

You can make a PR to make it a bindable property, we just made a custom class to wrap that and have a bindable property.

public class TintedCachedImage : CachedImage
    {
        public static BindableProperty TintColorProperty = BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(TintedCachedImage), Color.Transparent, propertyChanged: UpdateColor);

        public Color TintColor
        {
            get { return (Color)GetValue(TintColorProperty); }
            set { SetValue(TintColorProperty, value); }
        }

        private static void UpdateColor(BindableObject bindable, object oldColor, object newColor)
        {
            var oldcolor = (Color)oldColor;
            var newcolor = (Color)newColor;

            if (!oldcolor.Equals(newcolor))
            {
                var view = (TintedCachedImage)bindable;
                var transformations = new System.Collections.Generic.List<ITransformation>() {
                    new TintTransformation((int)(newcolor.R * 255), (int)(newcolor.G * 255), (int)(newcolor.B * 255), (int)(newcolor.A * 255)) {
                        EnableSolidColor = true
                    }
                };
                view.Transformations = transformations;
            }
        }
    }

All 13 comments

What is the specific error you get and what version of FF are you on?

The last version I'v used, It is not possible to bind HexColor property, in all of examples, there is no any example for binding TintTransformation.

Oh HexColor is not defined as a bindable property.

You can make a PR to make it a bindable property, we just made a custom class to wrap that and have a bindable property.

public class TintedCachedImage : CachedImage
    {
        public static BindableProperty TintColorProperty = BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(TintedCachedImage), Color.Transparent, propertyChanged: UpdateColor);

        public Color TintColor
        {
            get { return (Color)GetValue(TintColorProperty); }
            set { SetValue(TintColorProperty, value); }
        }

        private static void UpdateColor(BindableObject bindable, object oldColor, object newColor)
        {
            var oldcolor = (Color)oldColor;
            var newcolor = (Color)newColor;

            if (!oldcolor.Equals(newcolor))
            {
                var view = (TintedCachedImage)bindable;
                var transformations = new System.Collections.Generic.List<ITransformation>() {
                    new TintTransformation((int)(newcolor.R * 255), (int)(newcolor.G * 255), (int)(newcolor.B * 255), (int)(newcolor.A * 255)) {
                        EnableSolidColor = true
                    }
                };
                view.Transformations = transformations;
            }
        }
    }

I guessed, thank you for your solution, It solved.

Glad to help!

Yes, transformations properties are not bindable as they must also work in a non Xamarin.Forms projects. But that will change soon, as we're including Transformations packages in a base nugets, so we can add Xamarin.Forms specific Transformations for that which can have bindable properties :) I created issue for this: https://github.com/luberda-molinet/FFImageLoading/issues/499

@EmmanVazz Nice idea! :)

Hi guys, do you have any news about transformation on the forms?

I'm getting error with next statement HexColor="{StaticResource PrimaryDark}"

@JTOne123 What's error stack trace? HexColor must be a string, not XF Color struct.

Be sure, XF color there :)

I guess, it will be nice to have property for StaticResource :) And you told about XF transformation...

at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value)
   at Xamarin.Forms.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)

XF transformations are the same as native transformations (cross platform), that's why they can;t use XF specific types as Color

@EmmanVazz solution is perfect
but how if I wanted to add tint color to the SVG image
while that is easy in code by doing it like
var Icon = new TintedCachedImage();
Icon.Source = SvgImageSource.FromFile(_icon);

Well I don't know how to do it in Xaml

Well
I managed to find a solution for the problem I posted in the recent comment

`public class TintedCachedImage : CachedImage
{
public static BindableProperty TintColorProperty = BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(TintedCachedImage), Color.Transparent, propertyChanged: UpdateColor);

    public Color TintColor
    {
        get { return (Color)GetValue(TintColorProperty); }
        set { SetValue(TintColorProperty, value); }
    }

    private static void UpdateColor(BindableObject bindable, object oldColor, object newColor)
    {
        var oldcolor = (Color)oldColor;
        var newcolor = (Color)newColor;

        if (!oldcolor.Equals(newcolor))
        {
            var view = (TintedCachedImage)bindable;
            var transformations = new System.Collections.Generic.List<ITransformation>() {
                new TintTransformation((int)(newcolor.R * 255), (int)(newcolor.G * 255), (int)(newcolor.B * 255), (int)(newcolor.A * 255)) {
                    EnableSolidColor = true
                }
            };
            view.Transformations = transformations;
        }
    }

    //To Support SVG
    public static BindableProperty SvgSourceProperty = BindableProperty.Create(nameof(TintColor), typeof(string), typeof(TintedCachedImage), null, propertyChanged: UpdateSvg);
    public string SvgSource
    {
        get { return (string)GetValue(SvgSourceProperty); }
        set { SetValue(SvgSourceProperty, value); }
    }

    private static void UpdateSvg(BindableObject bindable, object oldVal, object newVal)
    {
        var _instance = bindable as TintedCachedImage;
        _instance.Source = SvgImageSource.FromFile((string)newVal);
    }
}`

I added a custom property to enable directly loading svg image from xml

usage

<local:TintedCachedImage Grid.Row="0" SvgSource="reset.svg" TintColor="{StaticResource BrandColor}" />

@MosCD

//To Support SVG
public static BindableProperty SvgSourceProperty = BindableProperty.Create(nameof(TintColor), ...

Probably you meant:

public static BindableProperty SvgSourceProperty = BindableProperty.Create(nameof(SvgSource), ...

Thank you anyway.

Was this page helpful?
0 / 5 - 0 ratings