INotifyPropertyChanged 和计算属性
假设我有一个简单的类 Order,它有一个 TotalPrice 计算属性,可以绑定到 WPF UI
public class Order : INotifyPropertyChanged
{
public decimal ItemPrice
{
get { return this.itemPrice; }
set
{
this.itemPrice = value;
this.RaisePropertyChanged("ItemPrice");
this.RaisePropertyChanged("TotalPrice");
}
}
public int Quantity
{
get { return this.quantity; }
set
{
this.quantity= value;
this.RaisePropertyChanged("Quantity");
this.RaisePropertyChanged("TotalPrice");
}
}
public decimal TotalPrice
{
get { return this.ItemPrice * this.Quantity; }
}
}
在影响 TotalPrice 计算的属性中调用 RaisePropertyChanged("TotalPrice") 是一个好习惯吗?刷新 TotalPrice 属性的最佳方法是什么? 当然,执行此操作的另一个版本是更改像这样的属性
public decimal TotalPrice
{
get { return this.ItemPrice * this.Quantity; }
protected set
{
if(value >= 0)
throw ArgumentException("set method can be used for refresh purpose only");
}
}
并调用 TotalPrice = -1 而不是 this.RaisePropertyChanged("TotalPrice");在其他属性中。请提出更好的解决方案
非常感谢
Suppose I have simple class Order, that have a TotalPrice calculated property, which can be bound to WPF UI
public class Order : INotifyPropertyChanged
{
public decimal ItemPrice
{
get { return this.itemPrice; }
set
{
this.itemPrice = value;
this.RaisePropertyChanged("ItemPrice");
this.RaisePropertyChanged("TotalPrice");
}
}
public int Quantity
{
get { return this.quantity; }
set
{
this.quantity= value;
this.RaisePropertyChanged("Quantity");
this.RaisePropertyChanged("TotalPrice");
}
}
public decimal TotalPrice
{
get { return this.ItemPrice * this.Quantity; }
}
}
Is it a good practice to call RaisePropertyChanged("TotalPrice") in the properties that affect to TotalPrice calculation? What is the best way to refresh TotalPrice property?
The other version to do this of course is to change property like this
public decimal TotalPrice
{
get { return this.ItemPrice * this.Quantity; }
protected set
{
if(value >= 0)
throw ArgumentException("set method can be used for refresh purpose only");
}
}
and call TotalPrice = -1 instead of this.RaisePropertyChanged("TotalPrice"); in other properties. please suggest solutions better
Thanks a lot
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
另一种解决方案是罗伯特·罗斯尼在此问题中提出的解决方案:
WPF INotifyPropertyChanged对于链接的只读属性,
您可以创建一个属性依赖关系图(使用他的代码示例):
然后在 OnPropertyChanged 中执行此操作:
您甚至可以附加一个属性,将依赖属性与它所依赖的属性联系起来。比如:
我还没有实现该属性的详细信息。我最好现在就开始做这件事。
Another solution is the one Robert Rossney proposed in this question:
WPF INotifyPropertyChanged for linked read-only properties
You can create a property dependency map (using his code samples):
and then do this in your OnPropertyChanged:
You can even attach an attribute to tie the dependent property to the one it depends on. Something like:
I haven't implemented the details of the attribute yet. I'd better get to working on that now.
可以检查一下是否应该从可能更改该值的任何其他成员处引发此事件,但只有在您确实更改该值时才这样做。
您可以将其封装在一个方法中:
然后您需要从其他变异成员中调用该方法:
It's fine to check to see if you should raise this event as well from any other member that may change the value, but only do so if you actually change the value.
You could encapsulate this in a method:
Then you need to call that from your other mutating members:
不,不是,它无法扩展,并且(属性应该知道依赖于它的所有内容这一事实)是维护噩梦
https://github.com/StephenCleary/CalculatedProperties 是目前 MVVM 最好的公式引擎(在我看来),它通知派生/计算属性的更改并支持任何级别的嵌套,最重要的是树依赖关系可以跨越多个对象,并且可以在运行时动态更改。
这与 Excel 公式非常相似,但适用于 MVVM。 ItemPrice 和 Quantity 不知道什么取决于它们,也不关心为依赖的 TotalPrice 提高 PropertyChanged。依赖关系树可以根据需要具有任意多个级别。
No, it's not, it doesn't scale and (the fact that property should know everything that depends on it) is a maintenance nightmare
https://github.com/StephenCleary/CalculatedProperties is best formula engine as of now for MVVM (in my opinion) that notifies about changes of derived/calculated properties and supports any level of nesting, most importantly tree of dependencies can span across multiple objects and can dynamically change at runtime.
This is very similar to Excel formulas but for MVVM. ItemPrice nor Quantity don't know what depends on them and don't care about raising PropertyChanged for dependant TotalPrice. Tree of dependencies can have as many levels as needed.
如果您使用NotifyPropertyWeaver,您可以获得此代码
并且它将被编译为此代码。
If you use NotifyPropertyWeaver you can have this code
And it will be compiled to this.
考虑使用 DependencyTracker,它是一个轻量级库,支持广泛的依赖项(您的示例,链,收藏品)。您甚至不必从任何特定的类派生您的类,或者用任何特殊对象包装您的依赖属性即可使其正常工作。
Consider using DependenciesTracker, it is a lightweight library that supports a wide range of dependencies (your example, chains, collection items). You even don't have to derive your class from any specific class or wrap your dependent property with any special object to get it worked.