2011-07-14 23 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」布爾值。儘管如此,這種類型的模式確實有一定的侷限性,如果由於某種原因代碼集的兩個部分將controlledChange設置爲true,那麼第一個'out'將在它應該出現之前將其設置回false。根據我的經驗,這種情況通常很少見,但可能會根據情況發生。解決這個問題的時間比我能在這裏得到的時間要長。 ;) – Yoopergeek

+0

你可能會考慮在這種情況下引入互斥量。 –

+0

如何將鞭炮放在答案上,讓每個人都可以看到它,以及它的美麗簡潔? – zazkapulsk

1

我不知道我完全理解,因爲我不知道你的「無限」是什麼意思

這可能是一個很好的用例實際上領域支持你的屬性。這樣,您可以在屬性集上觸發事件,但每次在內部設置一個字段而不觸發N個事件。

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"); 
    } 

也許你可以集中在更少的方法甚至可以單獨一個重新計算,但我不知道你是如何計算它們。但是當你重新計算價值時,你必須保持特定的順序。 由於它們只對字段進行操作並且不更改屬性,因此不會有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)); 
     } 
    } 
} 

什麼,他可能會做正在處理中。因此他提到,導致制定者的循環調用各個setter方法等性能。

維傑