In this excellent article, Nish Anil describes how to modify controls using Effects – a lighter weight approach than creating custom renderers. His examples, however, are all in C#, so I decided to translate them into XAML.
To begin I created a new Xamarin.Forms project named xamlEffects. There are two parts to creating the effect. The first is platform dependent. Optionally, create a folder in the iOS project named Platform. In that folder, add a file named RedSliderEffect.cs. You’ll also create files named BlueSliderEffect and GreenSliderEffect.
This code is right out of the original article:
[assembly: ResolutionGroupName(“EffectsSample”)]
[assembly: ExportEffect(typeof(RedSliderEffect), “RedSliderEffect”)]
namespace xamlEffects.iOS {
public class RedSliderEffect : PlatformEffect {
public RedSliderEffect() {
}
protected override void OnAttached() {
var slider = (UISlider)Control;
slider.ThumbTintColor = UIColor.FromRGB(255, 0, 0);
slider.MinimumTrackTintColor = UIColor.FromRGB(165, 165, 255);
slider.MaximumTrackTintColor = UIColor.FromRGB(14, 14, 255);
}
protected override void OnDetached() {
}
}
}
Notice that we override two methods: OnAttached and OnDetached. The idea is that the effect extends the control, and so we attach the effect to the control we wish to extend and then detach and clean up if needed after we’re done.
In this code, we’re setting the slider to a red dot on a blue line.
The important thing to notice are the two attributes. The first, ResolutionGroupName is only entered once per program. The second, ExportEffect is used once per effect. The name of the effect is the concatenation of the two; in this case EffectsSample.RedSliderEffect.
The PCL and the XAML
In the PCL we’ll create a class that derives from RoutingEffect for each effect we create. All this class needs to do is to pass up to the RoutingEffect the name we just created.,
using System;
using Xamarin.Forms;
namespace xamlEffects {
public class RedSliderEffect : RoutingEffect {
public RedSliderEffect()
: base(“EffectsSample.RedSliderEffect”) {
}
}
}
Now we can turn to the XAML. We add a slider to the page, and then within the slider tags we need to add a RedSliderEffect to the Slider’s Effects collection. This is done in the standard fashion for XAML:
<Slider
x:Name=”redSlider”
Minimum=”0″
Maximum=”100″>
<Slider.Effects>
<local:RedSliderEffect />
</Slider.Effects>
</Slider>
(Note that you’ll need to declare the “local” name space using the current assembly),
xmlns:local=”clr-namespace:xamlEffects;assembly=xamlEffects”
That’s all there is to it. This allows for significant changes to a control without creating custom renderers, a meaningful savings in development time and complexity.
Adding A Second Slider
You may very well want more than one slider with the same effect, but perhaps different colors. To do so, create a second effect in the platform dependent code. This is just like the first one, except, as noted, it has only one annotation:
[assembly: ExportEffect(typeof(BlueSliderEffect), “BlueSliderEffect”)]
namespace xamlEffects.iOS {
public class BlueSliderEffect : PlatformEffect {
public BlueSliderEffect() {
}
You’ll need a BlueSliderEffect.cs class in the PCL (just like the red slider effect but replacing “red” with “blue” (!)
Finally, in the Xaml, create a second slider,
<StackLayout
Padding=”50″>
<Slider
x:Name=”redSlider”
Minimum=”0″
Maximum=”100″>
<Slider.Effects>
<local:RedSliderEffect />
</Slider.Effects>
</Slider>
<Slider
x:Name=”blueSlider”
Minimum=”0″
Maximum=”100″>
<Slider.Effects>
<local:BlueSliderEffect />
</Slider.Effects>
</Slider>
</StackLayout>