Creating Text Shadow Effects In Xamarin Forms UWP

Creating Text Shadow Effects In Xamarin Forms UWP
We all love drop shadows on our titles and headers, button text, anywhere we want the text to really pop. Who doesn’t?
While it’s still not as easy as we’d like it to be, text shadows are possible using Xamarin Forms Effects. Effects are much like custom renderers, but easier to use. Though not having as much flexibility as renderers, effects are perfect for modifications to controls (such as a label that needs a drop shadow).
Xamarin (and its contributors) have provided an excellent example on Github and it works perfectly fine for Android, but when it came to UWP and all its peculiarities (for our needs at least), our team felt it needed to go a bit further. We’ve provided code below that is a modification of their fine work.
ShadowEffect goes inside the core project.
For neatness and clarity, we like to put our effects inside an Effects folder within the Xamarin Forms core project, but a separate folder isn’t necessary. It’s entirely up to you.
If you compare the below code with the Github sample, you will see that we’ve added more control over the shadow effect by including Opacity, FontAttributes, FontSize (with a Xamarin Forms font converter to allow font sizes such as micro or header instead of just numbers) and a custom FontFamily if desired.
Also, we’ve added more placement control by including HorizontalOptions, VerticalOptions, HorizontalTextAlignment, and VerticalTextAlignment.
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace OurProject.Effects
{
public class ShadowEffect : RoutingEffect
{
public ShadowEffect() : base("OurCompany.LabelShadowEffect")
{
}
public float Radius { get; set; } = 5;
public Color Color { get; set; } = Color.Black;
public float Opacity { get; set; } = 1.0f;
public float DistanceX { get; set; } = 3;
public float DistanceY { get; set; } = 3;
[Xamarin.Forms.TypeConverter(typeof(Xamarin.Forms.FontSizeConverter))]
public Double FontSize { get; set; }
public FontAttributes FontAttributes { get; set; } //= FontAttributes.None;
public string FontFamily { get; set; }
public Xamarin.Forms.LayoutOptions HorizontalOptions { get; set; } //= LayoutOptions.Fill;
public Xamarin.Forms.LayoutOptions VerticalOptions { get; set; } //= LayoutOptions.Fill;
public Xamarin.Forms.TextAlignment HorizontalTextAlignment { get; set; }// = TextAlignment.Start;
public Xamarin.Forms.TextAlignment VerticalTextAlignment { get; set; }// = TextAlignment.Start;
}
}
UWP Platform
Again, for neatness and clarity, we like to put our effects inside an Effects folder in the UWP Platform project.
We commented out the two fixed-value horizontal and vertical options in favor of a more-flexible solution. We also added in Opacity, FontAttributes, FontSize, and FontFamily, as well as HorizontalTextAlignment, and VerticalTextAlignment.
using System;
using System.Diagnostics;
using System.Linq;
using OurProject.UWP.Effects;
using OurProject.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ResolutionGroupName("OurCompany")]
[assembly: ExportEffect(typeof(LabelShadowEffect), nameof(LabelShadowEffect))]
namespace OurProject.UWP.Effects
{
public class LabelShadowEffect : PlatformEffect
{
bool shadowAdded = false;
protected override void OnAttached()
{
try
{
if (!shadowAdded)
{
var effect = (ShadowEffect)Element.Effects.FirstOrDefault(e => e is ShadowEffect);
if (effect != null)
{
var textBlock = Control as Windows.UI.Xaml.Controls.TextBlock;
var shadowLabel = new Label();
shadowLabel.Text = textBlock.Text;
shadowLabel.FontFamily = effect.FontFamily;
shadowLabel.FontSize = effect.FontSize;
shadowLabel.Opacity = effect.Opacity;
shadowLabel.FontAttributes = effect.FontAttributes;
//shadowLabel.HorizontalOptions = LayoutOptions.Center;
//shadowLabel.VerticalOptions = LayoutOptions.CenterAndExpand;
shadowLabel.HorizontalOptions = effect.HorizontalOptions;
shadowLabel.VerticalOptions = effect.VerticalOptions;
shadowLabel.HorizontalTextAlignment = effect.HorizontalTextAlignment;
shadowLabel.VerticalTextAlignment = effect.VerticalTextAlignment;
shadowLabel.TextColor = effect.Color;
shadowLabel.TranslationX = effect.DistanceX;
shadowLabel.TranslationY = effect.DistanceY;
((Grid)Element.Parent).Children.Insert(0, shadowLabel);
shadowAdded = true;
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
}
}
Importance of The Changes
When we tried to do anything custom – such as change the font size, the the TextAlignment, the FontFamily, or the FontAttributes – we ran into trouble, as the examples below will demonstrate.
No Custom FontFamily On The Shadow

No FontSize On The Shadow

No Vertical/Horizontal Options Or Alignment On The Shadow

All Settings Correct ON The Shadow

The Xaml - Which Must Be Enclosed In Its Own Grid
Even with all the custom coding, there were times when we just couldn’t get the shadow to show up.
Finally, we realized that either the label was in a Grid.ColumnSpan or a Stacklayout or any number of other situations we run across on a daily basis.
The one thing that always solved this problem was putting the label (along with its shadow) in its own grid. We first thought of using a Frame, but neither that nor a StackLayout would work.
It took quite a bit of work, but now that its done, the results are well worth it. Hope this helps you to make some text that really pops!
<Grid>
<Label
x:Name="TitleLabel"
FontSize="100"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
Style="{StaticResource TitleStyle}"
Text="Text Shadow Test!"
VerticalOptions="CenterAndExpand"
VerticalTextAlignment="Center">
<Label.FontFamily>
<OnPlatform x:TypeArguments="system:String">
<On Platform="Android">Inkfree.ttf#Ink Free</On>
<On Platform="UWP">/Fonts/Inkfree.ttf#Ink Free</On>
</OnPlatform>
</Label.FontFamily>
<Label.Effects>
<effects:ShadowEffect
DistanceX="5"
DistanceY="5"
FontAttributes="Bold"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
Radius="15"
VerticalOptions="CenterAndExpand"
VerticalTextAlignment="Center"
Color="Black">
<effects:ShadowEffect.FontFamily>
<OnPlatform x:TypeArguments="system:String">
<On Platform="Android">Inkfree.ttf#Ink Free</On>
<On Platform="UWP">/Fonts/Inkfree.ttf#Ink Free</On>
</OnPlatform>
</effects:ShadowEffect.FontFamily>
</effects:ShadowEffect>
</Label.Effects>
</Label>
</Grid>
What size battery backup do I need?

Surge Protector or Battery Backup?
Bottom Line: You don’t need a battery backup is you’re willing to lose your unsaved work. That being said, repeated shut offs from power outages can fragment your drive and cause you to need hard drive repair.
You may notice we didn’t ask “Do I need a surge protector?”
At the very least, every computer user should have a surge protector to protect them from sudden surges in electrical power. This happens more often than you might think. The electrical flow isn’t nearly as stable as some may think, under and over voltage being more the norm than the exception.
Surge protectors don’t have to cost a fortune. We really like this Belkin 12-Outlet Pivot-Plug Power Strip Surge Protector. It has an 8 foot Cord and is ideal for most home computers and audio / video centers. Check the current price on Amazon.
Let’s face it though—none of us enjoys having to replace unsaved work. it’s a pain in the *** and is so easily avoided.
Battery Backups, most commonly known as Uninterruptible Power Supplies (UPS) have saved many a computer user hours of misery having to redo work that may never be as good as the previous attempt. At less than $200 (USD) for a very dependable unit, they are well worth the investment. Most come with well over a hundred thousand dollars in device replacement insurance if they fail to protect your system. We use a 1500 VA because we want as much time as we can to put the finishing touches on our work and shut down the computer. We wouldn’t recommend going below 1000 VA.
The UPS model we use is the CyberPower CP1500AVRLCD Intelligent LCD UPS System, 1500VA/900W, 12 Outlets, AVR, Mini-Tower. This model has 6 Battery Backup & Surge Protected Outlets and 6 Surge Protected Outlets—more than most we’ve seen. Check the current price on Amazon.
If your situation is unique and you’re still not sure whether to go with a UPs or just settle for a surge protector, our advice would be to err on the side of caution and go with the ups. Always better safe than sorry, right?