Math Value Converters

Yesterday I’ve posted the topic on Math Expression Interpreter. It’s handy to use for Math calculations with WPF Value Converters. See the code below.

/// <summary>
/// Converts the input value to other value using the string
/// parameter value as the math expression.
/// </summary>
public class MathConverter : IValueConverter
{
    #region IValueConverter Members
    /// <summary>
    /// Converts the input <paramref name="value"/> to other value using the string
    /// <paramref name="parameter"/> value as the math expression.
    /// </summary>
    /// <param name="value">The value produced by the binding source.</param>
    /// <param name="targetType">Output value type.</param>
    /// <param name="parameter">Math expression string.</param>
    /// <param name="culture">The culture used to convert to/form double values.</param>
    /// <returns>Either the value calculated by the expression given in <paramref name="parameter"/>
    /// or <see cref="DependencyProperty.UnsetValue"/>.</returns>
    public object Convert(object value, Type targetType, object parameter
        , CultureInfo culture)
    {
        if (value == null || parameter == null || !(parameter is string))
            return DependencyProperty.UnsetValue;
        try
        {
            Expression interpreter = new Expression(parameter as string);

            // Expression parameter.
            double expressionParameter;
            if (value is string)
                expressionParameter = double.Parse(value as string, culture.NumberFormat);
            else
                expressionParameter = (double)System.Convert.ChangeType(value, typeof(double)
                    , culture.NumberFormat);
            
            double result = interpreter.Evaluate(new double[] { expressionParameter });
            
            // The result to the target type
            if (double.IsNaN(result) || double.IsInfinity(result))
            {
                if (targetType == typeof(double))
                    return result;
                else if (targetType == typeof(float))
                {
                    if (double.IsNaN(result))
                        return float.NaN;
                    else if (double.IsPositiveInfinity(result))
                        return float.PositiveInfinity;
                    else if (double.IsNegativeInfinity(result))
                        return float.NegativeInfinity;
                }

                return DependencyProperty.UnsetValue;
            }

            return System.Convert.ChangeType(result, targetType, culture.NumberFormat);
        }
        catch (Exception)
        {
            return DependencyProperty.UnsetValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter
        , CultureInfo culture)
    {
        throw new NotImplementedException();
    }
    #endregion IValueConverter Members
}

/// <summary>
/// Converts the input array of values to other value using the string
/// parameter value as the math expression.
/// </summary>
public class MathMultiConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members
    /// <summary>
    /// Converts the input <paramref name="values"/> to other value using the string
    /// <paramref name="parameter"/> value as the math expression.
    /// </summary>
    /// <param name="values">The value array produced by the binding source.</param>
    /// <param name="targetType">Output value type.</param>
    /// <param name="parameter">Math expression string.</param>
    /// <param name="culture">The culture used to convert to/form double values.</param>
    /// <returns>Either the value calculated by the expression given in <paramref name="parameter"/>
    /// or <see cref="DependencyProperty.UnsetValue"/>.</returns>
    public object Convert(object[] values, Type targetType, object parameter
        , CultureInfo culture)
    {
        if (values == null || parameter == null || !(parameter is string))
            return DependencyProperty.UnsetValue;
        try
        {
            Expression interpreter = new Expression(parameter as string);

            // Expression parameters array.
            double[] expressionParameters = new double[values.Length];
            for (int i = 0; i < values.Length; i++)
            {
                if (values[i] is string)
                    expressionParameters[i] = double.Parse(values[i] as string, culture.NumberFormat);
                else
                    expressionParameters[i] = (double)System.Convert.ChangeType(values[i]
                        , typeof(double), culture.NumberFormat);
            }
            
            double result = interpreter.Evaluate(expressionParameters);

            // The result to the target type
            if (double.IsNaN(result) || double.IsInfinity(result))
            {
                if (targetType == typeof(double))
                    return result;
                else if (targetType == typeof(float))
                {
                    if (double.IsNaN(result))
                        return float.NaN;
                    else if (double.IsPositiveInfinity(result))
                        return float.PositiveInfinity;
                    else if (double.IsNegativeInfinity(result))
                        return float.NegativeInfinity;
                }

                return DependencyProperty.UnsetValue;
            }
            return System.Convert.ChangeType(result, targetType, culture.NumberFormat);
        }
        catch (Exception)
        {
            return DependencyProperty.UnsetValue;
        }
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter
        , CultureInfo culture)
    {
        throw new NotImplementedException();
    }
    #endregion IMultiValueConverter Members
}

 

The first one is for use with the regular Binding class, and the second is for the MultiBinding.

Regards,
Oleg V. Polikarpotchkin

Advertisements

About ovpwp

I am engaged in programming, maintenance and supply of computing technique since 1970. Started with the computers M, BESM, Minsk series and received appropriate education in the least, in which it was then possible in THE USSR. Then he went the usual way - ES series, IBM 360/370, Sun Spark, Ibm Power & PS2, PC. Programming started in the code (machine commands), then were sorts of assemblers, Algol, FORTRAN, PL/1, C, C , VB, C#. It is only the ones that I used the production scale; but there were, of course, others like List, Modula, Pascal, Java, etc. Currently I prefer .NET platform for desktop development. I don't really like web-programming (probably because of the inability for quality design), but I have enough experience in site building in LAMP environment using PHP.
This entry was posted in Uncategorized. Bookmark the permalink.

One Response to Math Value Converters

  1. Unknown says:

    This blog is very informative. I love blogging when it is for or about something I believe in. I also read news blogs often and find that it makes me feel more intelligent every time I read them. I also feel like I am a pretty good person who tries to treat others with respect, no matter what their opinion is. There are some real haters out there. Thanks again. I learned a few things about blogging. I will definitely put your site on my speed dial.Thankshttp://www.vanjobb.huhttp://www.vanjobb.hu/mobilinternet.php?11http://www.vanjobb.hu/Bankbetetkamatok.php?22http://www.vanjobb.hu/nevnapokdatumszerint.php?39http://www.vanjobb.hu/nevnapoknaptar.php?41http://www.vanjobb.hu/nevnapok.php?40

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s