justin peterson
justin peterson

Reputation: 377

Properties value reflects another's

I am creating a Loan Calculator and I have 3 TextBoxes that I am trying to get to reflect one another. After I change the input of one of the TextBoxes I want the other 2 to recalculate based off the input either by pressing a calculate button that I have on my program or after the TextBox loses focus.

The three TextBoxes I've got are bound to certain values that get set upon the program being ran as well as the ability to be changed at run time:

     <TextBox Width="55" Height="23" Style="{StaticResource ResourceKey=StandardTextbox}" Text="{Binding StringFormat={}{0:P}, Path=CurrentLoan.PropertyTaxRate, Converter={StaticResource TextBoxToDecimalConverter1}}"/>

     <TextBox Width="65" Height="23" Style="{StaticResource ResourceKey=StandardTextbox}" Text="{Binding StringFormat={}{0:C}, Path=CurrentLoan.PropertyTaxMonth, Converter={StaticResource TextBoxToDecimalConverter1}}"/>

     <TextBox Width="65" Height="23" Style="{StaticResource ResourceKey=StandardTextbox}" Text="{Binding StringFormat={}{0:C}, Path=CurrentLoan.PropertyTaxYear, Converter={StaticResource TextBoxToDecimalConverter1}}"/>

     CurrentLoan.PropertyTaxRate = .012;
     CurrentLoan.PropertyTaxMonth = 250;
     CurrentLoan.PropertyTaxYear = 3000;

     SharedValues.HomeValue = 250000;

For a home that has a value of $250,000 and has a TaxRate at 1.2%, the yearly payment is $3000 (250,000 * .012) and the monthly payment is $250 (3,000 / 12 months in a year).

Also I've got the properties already declared like so:

  public double PropertyTaxRate
  {
     get { return _propertyTaxRate; }
     set { SetValueAndNotify(() => PropertyTaxRate, ref _propertyTaxRate, (value > 1) ? value / 100 : value); }
  }

  public double PropertyTaxMonth
  {
     get { return _propertyTaxMonth; }
     set { SetValueAndNotify(() => PropertyTaxMonth, ref _propertyTaxMonth, value); }
  }

  public double PropertyTaxYear
  {
     get{ return _propertyTaxYear; }
     set { SetValueAndNotify(() => PropertyTaxYear, ref _propertyTaxYear, value); }
  }

The SetValueAndNotify method simply just sets the value to the backing property and notifies the GUI that the property has changed using INotifyPropertyChanged.

Say if I change the PropertyTaxYear property to $6,000 I want the PropertyTaxMonth to change to $500 and the PropertyTaxRate to change to 2.4%. Anyone have an Idea on how to do this and make the properties reflect one another? Thank you in advanced for your input!

Upvotes: 0

Views: 124

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112712

Try this and be careful to avoid endless recursions. It helps to check if (value != <old value>). Also call SetValueAndNotify before setting other related properties in order for this check to work.

public double PropertyTaxRate
{
    get { return _propertyTaxRate; }
    set { 
        if (value > 1) {
            value /= 100;
        }
        if (value != _propertyTaxRate) {
            SetValueAndNotify(() => PropertyTaxRate, ref _propertyTaxRate, value); 
            PropertyTaxYear = value * SharedValues.HomeValue;
        }
    }
}

public double PropertyTaxMonth
{
    get { return _propertyTaxMonth; }
    set {
        if (value != _propertyTaxMonth) {
            SetValueAndNotify(() => PropertyTaxMonth, ref _propertyTaxMonth, value); 
            PropertyTaxYear = 12 * value;
        }
    }
}

public double PropertyTaxYear
{
    get{ return _propertyTaxYear; }
    set { 
        if (value != _propertyTaxYear) {
            SetValueAndNotify(() => PropertyTaxYear, ref _propertyTaxYear, value);
            PropertyTaxMonth = value / 12;
            PropertyTaxRate = value / SharedValues.HomeValue;
        }
    }
}

UPDATE

The recursion problem is tougher than expected. Since SetValueAndNotify might trigger unexpected behaviors, I suggest to do all the calculations on the backing variables and to notify when finished. (I do not show the code of the still to create OnNotifyPropertyChanged method.)

private void Notify()
{
    OnNotifyPropertyChanged(() => PropertyTaxRate);
    OnNotifyPropertyChanged(() => PropertyTaxYear);
    OnNotifyPropertyChanged(() => PropertyTaxMonth);
}

public double PropertyTaxRate
{
    get { return _propertyTaxRate; }
    set { 
        if (value > 1) {
            value /= 100;
        }
        if (value != _propertyTaxRate) {
            _propertyTaxRate = value;
            _propertyTaxYear = value * SharedValues.HomeValue;
            _propertyTaxMonth = _propertyTaxYear / 12;
            Notify();
        }
    }
}

public double PropertyTaxMonth
{
    get { return _propertyTaxMonth; }
    set {
        if (value != _propertyTaxMonth) {
            _propertyTaxMonth = value;
            _propertyTaxYear = 12 * value;
            _propertyTaxRate =  _propertyTaxYear / SharedValues.HomeValue;
            Notify();
        }
    }
}

public double PropertyTaxYear
{
    get{ return _propertyTaxYear; }
    set { 
        if (value != _propertyTaxYear) {
            _propertyTaxYear = value;
            _propertyTaxMonth = value / 12;
            _propertyTaxRate = value / SharedValues.HomeValue;
            Notify();
        }
    }
}

Upvotes: 1

Related Questions