views:

4151

answers:

2

I am creating a custom WPF control that let's say for simplicity sake has a vertical stack panel with a "title" TextBlock, followed by a ContentPresenter. I want the font size for the "title" to be 5 Points LARGER than the size used in the content, which is inherited by whatever container the user places this control in.

How can I specify a font size in the control template for the header element using a relative value without exposing a property like "TitleFontSize" to the user? I want do "add 5".

I tried using a ScaleTransform on the header text block with mixed results (the text block scaled fine but the orientation was modified - I had the text right-justified and it moved "off the control" area when scaled). Also, I am not sure if scale transform would be approprite here.

A: 

I did it with an IValueConverter as follows:

Created a class FontSizeConverter that derives from IValueConverter. The Convert method adds 10 to the value, and the ConvertBack method subtracts 10.

public class FontSizeConverter : IValueConverter
{

 #region IValueConverter Members

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return (double)value + 12.0;
 }

 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return (double)value - 12.0;
 }

 #endregion
}

Next, I declaried an instance of this class in the XAML template for the control:

<Style.Resources>
        <local:FontSizeConverter x:Key="fontSizeConverter"/>
</Style.Resources>

And Finnaly, the FontSize binding uses this converter applied to the inherited FontSize property:

<TextBlock FontSize="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FontSize, Converter={StaticResource fontSizeConverter}}" 
                                   Grid.Row="0" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                                   Path=Date.Day}" HorizontalAlignment="Right" VerticalAlignment="Top" Padding="2" Margin="2" >
 </TextBlock>

This works. But I still do not know if this is the correct answer. Let me know if there is a better way, or if this is appropriate.

Bill
Looks good to me, the only change I would make is to pass the value that's being added to the FontSize through the ConverterParameter, rather than hard coding it in the converter.
Ian Oakes
As Ian said, I'd add a ConverterParameter but otherwise that looks good.
Donnelle
+2  A: 

A more generic way

Value converter

public class MathConverter : IValueConverter
{
    public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
    {
        return (double)value + double.Parse( parameter.ToString() );
    }

    public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
    {
        return null;
    }
}

Converter Resource

<my:MathConverter x:Key="MathConverter" />

XAML

<TextBlock FontSize="{Binding
                     RelativeSource={RelativeSource AncestorType={x:Type Window}},
                     Path=FontSize,
                     Converter={StaticResource MathConverter},
                     ConverterParameter=2}" />
Thomas