How do I keep a constant FontSize in WPF Viewbox?

font-size, resize, viewbox, wpf, xaml

Solution

`ViewBox` won't allow you to keep a constant font size, that's just not how it works. You need to put the text outside the view box for that to happen:

<Grid>
    <Viewbox Stretch="Uniform">
        <Canvas Width="100" Height="100">
            <Ellipse Width="100" Height="100" Stroke="Black"/>
        </Canvas>
    </Viewbox>
    <TextBlock TextAlignment="Center" FontSize="12">Top Center</TextBlock>
</Grid>

Note that I removed the Width property from the `TextBlock`, I just let it stretch for the width of the grid, letting the text alignment take care of the centering.

Or, you could get creative and bind the `FontSize` property to the `ActualWidth` of the `ViewBox` and having it scaled appropriately, for example:

Converter:

class ViewBoxConstantFontSizeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is double)) return null;
        double d = (double)value;
        return 100 / d * 12;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Usage:

<Window.Resources>
    ...
    <local:ViewBoxConstantFontSizeConverter x:Key="conv"/>
</Window.Resources>
...
<Viewbox Name="vb" Stretch="Uniform">
    <Canvas Width="100" Height="100">
        <Ellipse Width="100" Height="100" Stroke="Black"/>
        <TextBlock Width="100" TextAlignment="Center"
                   FontSize="{Binding ElementName=vb, 
                                      Path=ActualWidth, 
                                      Converter={StaticResource conv}}">
            Top Center
        </TextBlock>
    </Canvas>
</Viewbox>

Problem

I have a `Viewbox` with a number of `TextBlock`s that are scaled and positioned perfectly by the `ViewBox`. Something like this: ``` <Viewbox Stretch="Uniform"> <Canvas Width="100" Height="100"> <Ellipse Width="100" Height="100" Stroke="Black"/> <TextBlock Width="100" TextAlignment="Center" FontSize="12">Top Center</TextBlock> </Canvas> </Viewbox> ``` If the user resizes the `Viewbox` its contents are perfectly scaled to match. However I would like to keep the `FontSize` to 12 regardless of the actual size of the `Viewbox`. How can I do this? Can I do this in XAML without attaching to an `Resize` event?

Original source