Search code examples
c#wpfunit-conversion

Converting constantly updated units in textboxes on command


I have three textblocks whose text are bound to three different properties.

<TextBlock Style="{StaticResource textBlockStyle2}"
           Text="{Binding Path=TWD,
                          Mode=TwoWay,
                          UpdateSourceTrigger=PropertyChanged},
                          StringFormat={}{0:F1} M}" />
<TextBlock Style="{StaticResource textBlockStyle2}"
           Text="{Binding Path=Alt,
                          Mode=TwoWay,
                          UpdateSourceTrigger=PropertyChanged},
                          StringFormat={}{0:F1} M}" />
<TextBlock Style="{StaticResource textBlockStyle2}"
           Text="{Binding Path=Dep,
                          Mode=TwoWay,
                          UpdateSourceTrigger=PropertyChanged},
                          StringFormat={}{0:F1} M}" />

These are the properties in the viewmodel:

private double _TWD;
public double TWD
{
    get { return _TWD; }
    set { _TWD = value; OnPropertyChanged("TWD"); }
}

private double _Alt;
public double Alt
{
    get { return _Alt; }
    set { _Alt = value; OnPropertyChanged("Alt"); }
}

private double _Dep;
public double Dep
{
    get { return _Dep; }
    set { _Dep = value; OnPropertyChanged("Dep"); }
}

Now, these are in meters, which is what the 'M' is for in the StringFormat property of the textblocks. What I'm trying to do is, when I 'click' (via command) on a separate textblock (this will be inside of a button using a control template), I want to convert the values in the above textblocks to feet and add an 'F' after the value. Another click will convert it back to meters, and so on.

I was thinking about adding a command that just converted the values based on a bool isMeters. However, the values in the textblock are constantly updated (every second) and I don't want to have to call the function every time the values change. Is there a simpler way I'm not thinking of to achieve this functionality?

Note:

1 meter = 3.2808 ft
1ft = 0.3048 meter

Solution

  • I got it working using a converter.

    public class MetersToFeetConverter : IValueConverter
    {
        /// <summary>
        /// Converts meters to feet.
        /// </summary>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            value = (double)value * 3.2808;
            return (value.ToString() + " F"); 
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return Binding.DoNothing;
        }
    }
    

    Then in the viewmodel:

    private bool _isMeters = true;
    public bool IsMeters
    {
        get { return _isMeters; }
        set { _isMeters = value; OnPropertyChanged("IsMeters"); }
    }
    
    //called when I click the button to convert
    public void ConvertData(object parameter)
    {
        if (_isMeters == false)
        {
            IsMeters = true;
        }
        else
        {
            IsMeters = false;
        }
    }
    

    Then the xaml binding for the textboxes are like this, using a datatrigger:

    <Style.Triggers>
        <DataTrigger Binding="{Binding IsMeters, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="False">
            <Setter Property="Text" Value="{Binding Path=TWD, Converter={StaticResource metersToFeetConverter}}" />
        </DataTrigger>
    </Style.Triggers>
    

    Note: @haindl answer also worked, just didn't see it till after I did it this way.