Change FontSize with ElementBinding

Jakob Nielsen says: “Let users control font size”. Unfortunately in Silverlight the nice features of the WPF FlowDocument control are not available (yet). You cannot use the automatic font size feature of that control in a Silverlight app. But in Silverlight 3 ElementBinding enables you to bind a value to the FontSize attribute of a TextBlock. Using a Converter with a ConverterParameter, dynamic font size becomes available:

Click for working version...

The trick is to use TextBlock controls for your text and set it’s properties in a Style, like you would normally do. This time, leave the FontSize attribute out.

<Style x:Key=”Body” TargetType=”TextBlock”>
    <Setter Property=”FontFamily” Value=”Trebuchet MS” />
    <Setter Property=”TextWrapping” Value=”Wrap” />
<Style x:Key=”Header” TargetType=”TextBlock” BasedOn=”{StaticResource Body}”>
    <Setter Property=”FontWeight” Value=”Bold” />
<Style x:Key=”Caption” TargetType=”TextBlock” BasedOn=”{StaticResource Body}”>
    <Setter Property=”FontStyle” Value=”Italic” />
    <Setter Property=”Foreground” Value=”Gray” />

Create TextBlocks with these Styles and Text, but set the FontSize attribute to an ElementBinding with the Value of a small Slider.

<TextBlock x:Name=”txtHeader1″ Style=”{StaticResource Header}”  FontSize=”{Binding Value, ElementName=Slider, Converter={StaticResource FontSizeConverter}, ConverterParameter=H1}” Text=”Header 1″/>

<Slider x:Name=”Slider” Value=”10″ SmallChange=”1″ LargeChange=”12″ Minimum=”6″ Maximum=”72″ Width=”100″ />

The converter will set the FontSize for you. The ConverterParameter has string values from “H1” to “H7”, like you would use in HTML. You can set this to any string you like, but these seem to make sense…

The converter looks like this:

using System;
using System.Windows.Data;

namespace Converters
    public class FontSizeConverter : IValueConverter  
        public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)  
            double v = (double)value;

            if (parameter != null)
                string fontSizeString = parameter.ToString();
                if (!string.IsNullOrEmpty(fontSizeString))
                        case “H1” :
                            value = 2.4 * v;
                        case “H2” :
                            value = 1.8 * v;
                        case “H3” :
                            value = 1.4 * v;
                        case “H4” :
                            value = 1.2 * v;
                        case “H5” :
                            value = 1 * v;
                        case “H6” :
                            value = .8 * v;
                        case “H7″ :
                            value = .6 * v;
            value = System.Convert.ToInt32(value); // we need an integer, not double…
            return value.ToString(); // …but as a string

As you can see the value is updated with different multipliers, depending on the header parameter you pass in. H5 is the basic text size, used by the Body Text, so its multiplier is 1. You can play with these multipliers if you want a different effect.

Add the namespace to your XAML file and put the converter as a resource at the top of the file…

<UserControl x:Class=”ControlFontSize.MainPage”
        <cvs:FontSizeConverter x:Key=”FontSizeConverter” />

… and you’re good to go. Let users control text size!

Working code is on my SkyDrive… Njoy!