Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF TextBox Binding Percentage

Tags:

c#

format

wpf

I have to bind a TextBox to a % value. So I set the StringFormat Property on the Binding like this:

<TextBox Text="{Binding Path=BewertungsFaktore.Gewinn, StringFormat=P2, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxStyle}" HorizontalAlignment="Left"/>

That seems to work quite fine. But if I edit the value there are issues. As example if I enter a value of 1 the textbox should format this in 1%. But the main problem is it formats into 100.00%. Another question is if I am using a German Sys do I have to enter ',' instaed of a '.'?

like image 477
Florian Avatar asked Feb 19 '23 09:02

Florian


2 Answers

If you just use a string format like {0:F2}% then you will have to put up with database values like 4.23 to represent 4.23% which is unacceptable to me (until they introduce a "percentage" data type into SQL Server).

I created the following value converter to map percentage values in the TextBox like 4.2367% into database values like 0.042367:

public class PercentageConverter : IValueConverter
{
    //E.g. DB 0.042367 --> UI "4.24 %"
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var fraction = decimal.Parse(value.ToString());
        return fraction.ToString("P2");
    }

    //E.g. UI "4.2367 %" --> DB 0.042367
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //Trim any trailing percentage symbol that the user MAY have included
        var valueWithoutPercentage = value.ToString().TrimEnd(' ', '%');
        return decimal.Parse(valueWithoutPercentage)/100;
    }
}

Note how the formatting string (in this case "P2") only limits how many decimal places are displayed, not how many decimal places are passed to the underlying binding source.

like image 187
Brian Hinchey Avatar answered Feb 23 '23 17:02

Brian Hinchey


The StringFormat property controls only the output string of the bound value. "P2" simply multiplies the value by 100 and formats it with two decimal digits and a trailing " %". On input, this format is ignored.

If you also need to input percent value you would have to use a binding converter. Such a converter could also parse the input string in a culture-invariant way like this:

double fraction;
double percentage;
if (double.TryParse(value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out percentage))
{
    fraction = percentage / 100d;
}
like image 28
Clemens Avatar answered Feb 23 '23 18:02

Clemens