Can a mathematical operator be applied to the Binding path?

Old Geezer picture Old Geezer · Jun 29, 2012 · Viewed 15.8k times · Source

Can I have the following (the ActualWidth divided by 2)?

<StackPanel Name="SP2" Width="{Binding ElementName=SP1, Path=ActualWidth/2}">

Doesn't seem to work for me.

Thanks.

Answer

Paolo Moretti picture Paolo Moretti · Jun 29, 2012

You can use a custom converter to perform simple calculations directly in XAML.

Take a look, for example, at this implementation:

MathConverter

Simple usage:

<RotateTransform Angle="{Binding Text, ElementName=Seconds,
    Converter={ikriv:MathConverter}, ConverterParameter=x*6}" />

The classical approach is to create a readonly calculated property. So in this simple case you can add a second property HalfWidth.

public double HalfWidth
{
    get
    {
        return ActualWidth / 2.0;
    }
}

The bad news is that when ActualWidth is updated, the StackPanel on the view bound to HalfWidth will not update. This is because the view does not know that HalfWidth has changed.

By raising a property changed event on HalfWidth in the setter of ActualWidth, the view will query HalfWidth and hence retrieve the correct value.

private double _actualWidth;
public double ActualWidth
{
    get
    {
        return _actualWidth;
    }
    set
    {
        if (_actualWidth != value)
        {
            _actualWidth = value;
            OnPropertyChanged("ActualWidth");
            OnPropertyChanged("HalfWidth");
        }
    }
}

The main proplem about this approach is that it will soon become a nightmare when we have numerous calculated properties with no setters.

That's why (in a MVVM pattern) I personally prefer to use a custom converter.