2011-07-14 22 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方法等性能。

维杰