2011-07-14 13 views
1

私は、販売価格、前払金額、前払い率、および融資額があるとします。これらのプロパティのいずれかがユーザによって変更された場合、新しい値を反映するために他のプロパティを更新する必要があります。このような無限の不動産変更イベントはどのように扱いますか?無限のプロパティ変更を防止する方法

+1

私は混乱しています - これは何が無限になりますか? – Matt

+0

この場合、前払金の割合がどのように丸められているかに関係します。そうしないと、値が同じ値を計算し、プロパティー変更イベントの発生を停止するポイントに達する可能性があります。 –

答えて

2

最も簡単な方法は、プロパティが本当にが変更持っている場合にのみ変更イベントを高めることです:

フロー制御は、複数の属性間で必要である
public decimal SalePrice { 
    get{ 
     return salePrice; 
    } 
    set { 
     if (salePrice != value) { 
      salePrice = value; // putting as first statement prevents the setter 
          // to be entered again ... 
      RaiseSalePriceChange(); 
      // Set other properties 
     } 
    } 
} 
4

、私はフロー制御変数を提起ます - ブール - 変更されている各プロパティで、私がフロー制御下にあるかどうかを確認するテストを追加します。

private bool controlledChange = false; 

public property int MyVal1 
{ 
    set 
    { 
     _myVal1 = value; 
     if(!controlledChange) 
     { 
      controlledChange = true; 
      MyVal2 -= 1; 
      controlledChange = false; 
     } 
    } 
} 

public property int MyVal2 
{ 
    set 
    { 
     _myVal2 = value; 
     if(!controlledChange) 
     { 
      controlledChange = true; 
      MyVal1 += 1; 
      controlledChange = false; 
     } 
    } 
} 

プロパティが変更されたものは何でもこの方法は、他のプロパティ間の変更を開始することはできませんが、彼らは変更を取得するとき、彼らは順番に変化の独自のセットを開始しないでしょう。

これらのプロパティのうち、計算結果を持つことができる場合は、できるだけ多くのプロパティを読み取り、オブジェクトの変更方法を制限する必要があります。

+0

私はこれらの "STFU"ブーリアンと呼んでいます。このタイプのパターンには制限がありますが、何らかの理由で2つのセクションのコードがcontrolledChangeをtrueに設定した場合、最初の 'out'はそれをfalseに戻す前に設定します。そのような状況は私の経験ではまれですが、状況によっては起こる可能性があります。そのための修正は私がここに入るよりも長いです。 ;) – Yoopergeek

+0

あなたはおそらくその状況でミューテックスを導入することに目を向けるでしょう。 –

+0

誰もが爆竹を答えに載せるので、誰もがそれとその美しいシンプルさを見ることができますか? – zazkapulsk

1

私は私はあなたが「無限」

によって何を意味するのか分からないので、これは実際にフィールドであなたの特性をバックアップのために良いユースケースであってもよいし、私は完全に理解していません。こうすることで、プロパティーセットのイベントをトリガーできますが、N個のイベントをトリガーすることなく、一度に1つずつフィールドを内部的に設定できます。

class MyClass 
{ 
    private string m_Name; 
    private int m_SomeValue; 

    public string Name 
    { 
     get { return m_Name; } 
     set 
     { 
      if (value != m_Name) 
      { 
       m_Name = value; 
       m_SomeValue++; 

       // Raise Event 
      } 
     } 
    } 

    public int SomeValue 
    { 
     get { return m_SomeValue; } 
     set 
     { 
      if (m_SomeValue != value) 
      { 
       m_SomeValue = value; 
       // Raise Event 
      } 
     } 
    } 
0

INotifyPropertyChangedの場合は、実際に外部オブジェクトに通知するために必要とされているので、私はちょうど、すべてを一元管理します。

private double salesPrice; 
    private double downPaymentAmount; 
    private double downPaymentPercent; 
    private double loanAmount; 

    public double SalesPrice 
    { 
     get 
     { 
      return salesPrice; 
     } 
     set 
     { 
      if (salesPrice != value) 
      { 
       salesPrice = value; 

       // maybe you would rather use a RecalculateForSalePriceChanged() method 
       RecalculateDownPaymentAmount(); 
       RecalculateDownPaymentPercent(); 
       RecalculateLoanAmount(); 

       propertiesChanged(); 
      } 
     } 
    } 

    public double DownPaymentAmount 
    { 
     get 
     { 
      return downPaymentAmount; 
     } 
     set 
     { 
      if (downPaymentAmount != value) 
      { 
       downPaymentAmount = value; 

       // see above 
       RecalculateDownPaymentPercent(); 
       RecalculateLoanAmount(); 
       RecalculateSalesPrice(); 

       propertiesChanged(); 
      } 
     } 
    } 

    public double DownPaymentPercent 
    { 
     get 
     { 
      return downPaymentPercent; 
     } 
     set 
     { 
      if (downPaymentPercent != value) 
      { 
       downPaymentPercent = value; 

       // see above 
       RecalculateDownPaymentAmount(); 
       RecalculateLoanAmount(); 
       RecalculateSalesPrice(); 

       propertiesChanged(); 
      } 
     } 
    } 

    public double LoanAmount 
    { 
     get 
     { 
      return loanAmount; 
     } 
     set 
     { 
      if (loanAmount != value) 
      { 
       loanAmount = value; 

       // see above 
       RecalculateDownPaymentAmount(); 
       RecalculateDownPaymentPercent(); 
       RecalculateSalesPrice(); 

       propertiesChanged(); 
      } 
     } 
    } 

    private void propertiesChanged() 
    { 
     RaisePropertyChanged("SalesPrice", "DownPaymentAmount", "DownPaymentPercent", "LoanAmount"); 
    } 

再計算を少ない方法で、あるいは1つでも集中することはできますが、計算方法はわかりません。しかし確かに値を再計算するときには特定の順序を保つ必要があります。 これらはフィールドでのみ動作し、プロパティを変更しないため、PropertyChanged-feedback-loopはありません。

これがうまくいくと思っています。私はあなたが望むものを誤解しませんでした。

0

はOPが望んでいた彼がやっているかもしれない何を

class A : INotifyPropertyChanged 
{ 
    private int field1; 
    public int Property1 
    { 
     get { return field1; } 
     set 
     { 
      field1 = value; 
      field2++; 
      RaisePropertyChanged("Property1"); 
      RaisePropertyChanged("Property2"); 
     } 
    } 

    private int field2; 
    public int Property2 
    { 
     get { return field2; } 
     set 
     { 
      field2 = value; 
      field1++; 
      RaisePropertyChanged("Property1"); 
      RaisePropertyChanged("Property2"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

を次のようなものは、このようにセッターの巡回呼び出しにつながる彼が言及した各プロパティのセッターで他のプロパティを処理しました。

ビジェイ

関連する問題