Can you do "math" within WPF Styles that are data-bound

I have a button control style and I want to change the padding from whatever the data-bound version is to adjust for a glyph that needs a 2 pixel offset. I'll use SimpleButton from SimpleStyles.xaml as an example (... shows where the trigger code was removed for conciseness):

<Style x:Key="SimpleButton" TargetType="{x:Type Button}" BasedOn="{x:Null}">
  <Setter Property="FocusVisualStyle" Value="{DynamicResource SimpleButtonFocusVisual}"/>
  <Setter Property="Background" Value="{DynamicResource NormalBrush}"/>
  <Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>
  <Setter Property="Template">
        <ControlTemplate TargetType="{x:Type Button}">
            <!-- We use Grid as a root because it is easy to add more elements to customize the button -->
           <Grid x:Name="Grid">
             <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"/>

              <!-- Content Presenter is where the text content etc is placed by the control. The bindings are useful so that the control can be parameterized without editing the template -->
             <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>

What I want to do is add some extra margin where Padding="{TemplateBinding Padding}". Something like Padding="{TemplateBinding Padding} + 2,0,0,0".

Is there a XAML syntax to that? If not, is there a best approach when doing this in code (Decorator?) ?


Currently XAML does not parse expressions in Binding syntax, etc. However, you can use an IValueConverter or IMultiValueConverter to help yourself out:


    <ControlTemplate TargetType="{x:Type Button}">
       <Grid x:Name="Grid">
             <local:ThicknessAdditionConverter x:Key="AdditiveThickness" />
         <Border x:Name="Border">
                 <Binding Path="Padding" RelativeSource="{RelativeSource TemplatedParent}"
                          Converter="{StaticResource AdditiveThickness}">

IValueConverter code behind:

public class ThicknessAdditionConverter : IValueConverter
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        if (value == null) return new Thickness(0, 0, 0, 0);
        if (!(value is Thickness)) throw new ArgumentException("Value not a thickness", "value");
        if (!(parameter is Thickness)) throw new ArgumentException("Parameter not a thickness", "parameter");

        var thickness = new Thickness(0, 0, 0, 0);
        var t1 = (Thickness)value;
        var t2 = (Thickness)parameter;

        thickness.Left = t1.Left + t2.Left;
        thickness.Top = t1.Top + t2.Top;
        thickness.Right = t1.Right + t2.Right;
        thickness.Bottom = t1.Bottom + t2.Bottom;

        return thickness;

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        throw new NotImplementedException();

There is a product available at called Eval Binding and Simple Binding does this now. (The product is not free) Check out the whitepaper here

For example for the bellow XAML code you need a converter to do the operation.

<Ellipse Fill="Blue" Height="50"
    Width="{Binding RelativeSource={RelativeSource Self}, 
        Path=Height, Converter={StaticResource MyConverter}}" />

But with EvalBinding you can do like bellow

    <Ellipse Fill="Blue" Height="50"
    Width="{blendables:EvalBinding [{Self}.Height]/2}" />

No, not in this version of XAML - use a Value Converter to do your math.

Check out the ExpressionConverter in this library.

You can do some simple math by taking advantage of transforms.

Check out this trick that Charles Petzold came up with a long time ago:

Unfortunately, it doesn't seem to help your particular scenario ... since you want only to change Left property of the Thickness type for the Padding ... and that is not a dependency property that you can bind to alone.

However, I felt compelled to add this answer in the case it helps others who find their way here via Google or another search engine.

Check out the MathConverter:

There you can send in an expression as the converter-parameter, where @VALUE is the value you are binding to:


Need Your Help