Dr TJ
Dr TJ

Reputation: 3356

Entry value converter hangs converting and converting back again and again

I have an Entry which holds the Price and I wanted to format it as currency.
Here is the Entry tag

<Entry x:Name="Price" StyleId="Price"  
       Text="{Binding Model.Price, Converter={StaticResource CurrencyEntryFormatConverter}, Mode=TwoWay}"
       Placeholder="{x:Static resx:Resources.PricePlaceholder}"
       Style="{StaticResource DefaultEntry}" Keyboard="Numeric"/>

and here is the property in the Model

public decimal Price
{
    get
    {
        return this.price;
    }

    set
    {
        if (this.price== value)
        {
            return;
        }

        this.price= value;
        this.OnPropertyChanged();
    }
}

Finally here is the converter:

public class CurrencyEntryFormatConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
            return value;
        }

        string result = string.Format(Resources.CurrencyFormatString, (decimal)value);
        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
            return 0;
        }

        string result = value.ToString().Replace(" ", "").Replace("$", "").Replace(",", "");
        return result;
    }
}

Question: My problem is that when I run the project and try to enter values in the Price field, the code repeats executing between Convert and ConvertBack functions of the converter and application hangs!
Any advice?

Upvotes: 0

Views: 497

Answers (1)

Dr TJ
Dr TJ

Reputation: 3356

In my case the problem was the property implementation
If we define a property of a class which is implementing INotifyPropertyChanged, in order to update the view when the property value changes, we need to call OnPropertyChanged method in the set block:

public decimal Amount
{
    get
    {
        return this.amount;
    }

    set
    {
        this.amount = value;
        this.OnPropertyChanged();  // like this line
    }
}

But just this code like so makes a loop with your bindings. So we need to be checking if the value is different than the current property's value and then if its new, update it. Look at this code:

public decimal Amount
{
    get
    {
        return this.amount;
    }

    set
    {
        if (this.amount == value)
        {
            return;
        }

        this.amount = value;
        this.OnPropertyChanged();
    }
}

That if block helps you to stop looping between get and set. I hope it helps someone.

Upvotes: 1

Related Questions