模型中的计算特性
本文关键字:计算 模型 | 更新日期: 2023-09-27 18:28:24
祝你好运!
我的产品模型包含许多经典属性(代码、说明、含增值税价格、无增值税价格和增值税)。对于我的例子,我只列出了有趣的属性。
在这个模型中,我想添加价格计算。当任何金额变化时,计算其他属性(当增值税变化时,重新计算有增值税价格和无增值税价格,反之亦然)
我的例子:
public class Product : EditableObject
{
//VAT percentage propertie (ex: 20%)
private decimal _vat;
public decimal Vat
{
get { return _vat; }
set
{
_vat = value;
PriceWithVat = _priceWithoutVat * (1 + Vat / 100); //Vat changed, we recalculate Price WITH VAT propertie
PriceWithoutVat = _priceWithVat / (1 + Vat / 100); //Vat changed, we recalculate Price WITHOUT VAT propertie
NotifyOfPropertyChange(() => Vat);
}
}
//Product Price Without VAT
private decimal _priceWithoutVat;
public decimal PriceWithoutVat
{
get { return _priceWithoutVat; }
set
{
_priceWithoutVat = value;
PriceWithVat = _priceWithoutVat * (1 + Vat / 100); //PriceWithoutVat changed, we recalculate Price WITH VAT propertie
NotifyOfPropertyChange(() => PriceWithoutVat);
}
}
//Product Price WITH Vat
private decimal _priceWithVat;
public decimal PriceWithVat
{
get { return _priceWithVat; }
set
{
_priceWithVat = value;
PriceWithoutVat = _priceWithVat / (1 + Vat / 100); //PriceWithVat changed, we recalculate Price WITHOUT VAT propertie
NotifyOfPropertyChange(() => PriceWithVat);
}
}
}
有了这个,当任何价格变化时,我都有无限循环和堆栈溢出。正常,因为当任何价格变化时,所有其他价格都会重新计算,然后依次重新计算价格:)
当我的3个金额发生变化时,你有自动重新计算的解决方案吗?
不要使计算的属性读写。相反,为只读计算属性引发适当的PropertyChanged
,例如:
public decimal Price
{
get { return _price; }
set
{
if (_price != value)
{
_price = value;
NotifyOfPropertyChange(() => Price);
NotifyOfPropertyChange(() => PriceWithVat);
}
}
}
public decimal Vat
{
get { return _vat; }
set
{
if (_vat != value)
{
_vat = value;
NotifyOfPropertyChange(() => Vat);
NotifyOfPropertyChange(() => PriceWithVat);
}
}
}
public decimal PriceWithVat
{
get { return _price / (1 + _vat / 100); }
}
由于它们是计算的属性,因此不能直接设置它们的值。另一方面,为它们提高PropertyChanged
就足以从UI中重新读取它们的值。
更新
根据您的评论(尽管这是一个非常奇怪的要求),您可以通过更新支持字段值来实现您想要的。注意,为了避免StackoverflowException
:,您不能在此处调用属性设置程序
private void UpdatePriceWithVat()
{
_priceWithVat = _price * (1 + _vat / 100);
NotifyOfPropertyChange(() => PriceWithVat);
}
private void UpdatePrice()
{
_price = _priceWithVat / (1 + _vat / 100);
NotifyOfPropertyChange(() => Price);
}
public decimal Price
{
get { return _price; }
set
{
if (_price != value)
{
_price = value;
NotifyOfPropertyChange(() => Price);
UpdatePriceWithVat();
}
}
}
public decimal Vat
{
get { return _vat; }
set
{
if (_vat != value)
{
_vat = value;
NotifyOfPropertyChange(() => Vat);
UpdatePriceWithVat();
}
}
}
public decimal PriceWithVat
{
get { return _priceWithVat; }
set
{
if (_priceWithVat != value)
{
_priceWithVat = value;
NotifyOfPropertyChange(() => PriceWithVat);
UpdatePrice();
}
}
}
两个注意事项:
- 术语"计算"在这里不是最好的选择
- 若您添加更多的属性,这将影响其他属性,那么此类代码的复杂性将快速增长