Delpin Susai Raj Monday, 3 February 2020

Xamarin.Forms - Use BindableProperty in Effects

In this blog, you will learn how to use BindableProperty Effects in Xamarin.Forms


Tint Color Sample -  https://xamarinmonkeys.blogspot.com/2020/02/xamarinforms-tint-image-using-effects.html

(The Blog about change Image color at Runtime using Tint Color)


Introduction

Xamarin.Forms code runs on multiple platforms - each of which has its own filesystem. This means that reading and writing files are most easily done using the native file APIs on each platform. Alternatively, embedded resources are a simpler solution to distribute data files with an app.

Tint Image

TintImage is used for change image color at runtime with the help of effects, you can achieve with custom render also. Tint images mainly used to reduce the usage of the images.

BindableProperty

Attached properties can be used to define effect parameters that respond to runtime property changes. This article demonstrates using attached properties to pass parameters to an effect and changing a parameter at runtime.

Prerequisites
  • Visual Studio 2017 or later (Windows or Mac)
The Problem

We are not able to create a BindableProperty in Effect.

Solution

Create Effect

Now, Create a TintImage class inherit from RoutingEffect for Change image color.

TintImage.cs

public class TintImage: RoutingEffect
{
public Color TintColor { get; private set; }
public TintImage(Color color) : base($"MyCompany.{nameof(TintImage)}")
{
TintColor = color;
}
}
view raw TintImage.cs hosted with ❤ by GitHub
Create Static Class

Here, I'm Going to create a Static Class for creating BindableProperty to my Effect.

TintImageEffect.cs

public static class TintImageEffect
{
public static BindableProperty TintColorProperty =
BindableProperty.CreateAttached("TintColor",
typeof(Color),
typeof(TintImageEffect),
Color.Default,
propertyChanged: OnTintColorPropertyPropertyChanged);
public static Color GetTintColor(BindableObject element)
{
return (Color)element.GetValue(TintColorProperty);
}
public static void SetTintColor(BindableObject element, Color value)
{
element.SetValue(TintColorProperty, value);
}
static void OnTintColorPropertyPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
AttachEffect(bindable as Image, (Color)newValue);
}
static void AttachEffect(Image element, Color color)
{
var effect = element.Effects.FirstOrDefault(x => x is TintImage) as TintImage;
if (effect != null)
{
element.Effects.Remove(effect);
}
element.Effects.Add(new TintImage(color));
}
}
Android Implementation

Here, Implement Platform Effects for TintImage at Runtime.

TintImageImpl.cs

[assembly: ExportEffect(typeof(TintImageImpl), nameof(XamarinStudy.Common.Controls.TintImage))]
namespace XamarinStudy.Droid.Effects
{
public class TintImageImpl: PlatformEffect
{
protected override void OnAttached()
{
try
{
var effect = (XamarinStudy.Common.Controls.TintImage)Element.Effects.FirstOrDefault(e => e is XamarinStudy.Common.Controls.TintImage);
if (effect == null || !(Control is ImageView image))
return;
var filter = new PorterDuffColorFilter(effect.TintColor.ToAndroid(), PorterDuff.Mode.SrcIn);
image.SetColorFilter(filter);
}
catch (Exception ex)
{
}
}
protected override void OnDetached() { }
}
}
iOS Implementation

Here, Implement Platform Effects for TintImage at Runtime.

TintImageImpl.cs

[assembly: ExportEffect(typeof(XamarinStudy.iOS.Effects.TintImageImpl), nameof(TintImage))]
namespace XamarinStudy.iOS.Effects
{
public class TintImageImpl: PlatformEffect
{
protected override void OnAttached()
{
try
{
var effect = (XamarinStudy.Common.Controls.TintImage)Element.Effects.FirstOrDefault(e => e is XamarinStudy.Common.Controls.TintImage);
if (effect == null || !(Control is UIImageView image))
return;
image.Image = image.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
image.TintColor = effect.TintColor.ToUIColor();
}
catch (Exception ex)
{
}
}
protected override void OnDetached() { }
}
}
Create ViewModel

Now, Create a Property for Binding the TintColor to View. and Create ChangeColorCommand For Change image color at runtime.

MainPageViewModel.cs

public class MainPageViewModel:BaseViewModel
{
#region Fields
private Command _changeColorCommand;
private Color _imageColor;
#endregion
#region Constructor
public MainPageViewModel()
{
_imageColor = Color.Gray;
}
#endregion
#region Properties
public Color ImageColor
{
get { return _imageColor; }
set { Set(() => ImageColor, ref _imageColor, value); }
}
public Command ChangeColorCommand
{
get
{
return _changeColorCommand ?? (_changeColorCommand = new Command(() =>
{
if(this.ImageColor==Color.Black)
{
this.ImageColor = Color.Gray;
}
else
{
this.ImageColor = Color.Black;
}
}));
}
}
#endregion
}
Consuming the TintImage

Now, Use the TintImage Effect in your XAML code.

MainPage.xaml

<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:behaviors="clr-namespace:XamarinStudy.Common.Behaviors"
xmlns:converters="clr-namespace:XamarinStudy.Common.Converters"
xmlns:Effects="clr-namespace:XamarinStudy.Common.Controls"
x:Class="XamarinStudy.MainPage" Title="Effects">
<StackLayout Margin="10,30,10,0" Spacing="20">
<Image Source="banner.png"/>
<Image Source="favicon.png" Effects:TintImageEffect.TintColor="{Binding ImageColor}">
</Image>
</StackLayout>
</ContentPage>
view raw MainPage.xaml hosted with ❤ by GitHub
Click the "Play" button to try it out.

Wow, It's Working.😍

I hope you have understood how to use BindableProperty Effects in Xamarin.Forms.

Thanks for reading. Please share your comments and feedback. Happy Coding 🙌
Delpin Susai Raj Sunday, 2 February 2020

Xamarin.Forms - Tint Image Color Using Effects

In this blog post, you will learn how to Change image color using Tint Color Effects in Xamarin.Forms.

Introduction

Xamarin.Forms code runs on multiple platforms - each of which has its own filesystem. This means that reading and writing files are most easily done using the native file APIs on each platform. Alternatively, embedded resources are a simpler solution to distribute data files with an app.

Tint Color

TintImage is used for change image color at runtime with the help of effects, you can achieve with custom render also. Tint images mainly used for reducing the usage of the images.

Prerequisites
  • Visual Studio 2017 or later (Windows or Mac)
Create TintImage

The Actual Image Color is Blue 

Now, Create a TintImage class inherit from RoutingEffect for Change image color.

TintImage.cs

public class TintImage: RoutingEffect
{
public Color TintColor { get; private set; }
public TintImage(Color color) : base($"MyCompany.{nameof(TintImage)}")
{
TintColor = color;
}
}
view raw TintImage.cs hosted with ❤ by GitHub
Android Implementation

Here, Implement Platform Effects for TintImage at Runtime.

TintImageImpl.cs

[assembly: ExportEffect(typeof(TintImageImpl), nameof(XamarinStudy.Common.Controls.TintImage))]
namespace XamarinStudy.Droid.Effects
{
public class TintImageImpl: PlatformEffect
{
protected override void OnAttached()
{
try
{
var effect = (XamarinStudy.Common.Controls.TintImage)Element.Effects.FirstOrDefault(e => e is XamarinStudy.Common.Controls.TintImage);
if (effect == null || !(Control is ImageView image))
return;
var filter = new PorterDuffColorFilter(effect.TintColor.ToAndroid(), PorterDuff.Mode.SrcIn);
image.SetColorFilter(filter);
}
catch (Exception ex)
{
}
}
protected override void OnDetached() { }
}
}
iOS Implementation

Here, Implement Platform Effects for TintImage at Runtime.

TintImageImpl.cs

[assembly: ExportEffect(typeof(XamarinStudy.iOS.Effects.TintImageImpl), nameof(TintImage))]
namespace XamarinStudy.iOS.Effects
{
public class TintImageImpl: PlatformEffect
{
protected override void OnAttached()
{
try
{
var effect = (XamarinStudy.Common.Controls.TintImage)Element.Effects.FirstOrDefault(e => e is XamarinStudy.Common.Controls.TintImage);
if (effect == null || !(Control is UIImageView image))
return;
image.Image = image.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
image.TintColor = effect.TintColor.ToUIColor();
}
catch (Exception ex)
{
}
}
protected override void OnDetached() { }
}
}
Consuming the TintImage

Now, Use the TintImage Effect in your XAML code.

MainPage.xaml

<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:behaviors="clr-namespace:XamarinStudy.Common.Behaviors"
xmlns:converters="clr-namespace:XamarinStudy.Common.Converters"
xmlns:Effects="clr-namespace:XamarinStudy.Common.Controls"
x:Class="XamarinStudy.MainPage" Title="Effects">
<StackLayout Margin="10,30,10,0" Spacing="20">
<Image Source="banner.png"/>
<Image Source="favicon.png" Effects:TintImageEffect.TintColor="Green">
</Image>
</StackLayout>
</ContentPage>
view raw MainPage.xaml hosted with ❤ by GitHub
Click the "Play" button to try it out.

Wow, It's Working.😍

I hope you have understood how to Change image color using Tint Color Effects in Xamarin.Forms.

Thanks for reading. Please share your comments and feedback. Happy Coding 😀🙌