我有一个具有两个属性“数量”和“价格”的 Item 类,并实现 INotifyPropertyChanged
public class Item:INotifyPropertyChanged
{
private event PropertyChangedEventHandler _propertyChanged;
public event PropertyChangedEventHandler PropertyChanged
{
add { _propertyChanged += value; }
remove { _propertyChanged -= value; }
}
void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public int QuantityOnHand
{
get
{
return this._quantityOnHand;
}
set
{
if (value > 0)
{
this._quantityOnHand = value;
NotifyPropertyChanged();
}
else
{
throw new System.ArgumentException("Quantity must be a positive value!");
}
}
}
.....
}
我有一个名为“Inventory”的商品集合类,其属性为 TotalRetailPrice:
public class Inventory {
private List<Item> _inventoryList = new LinkedList<Item>();
public decimal TotalRetailPrice
{
get
{
decimal totalRetailPrice = 0M;
foreach (var item in _inventoryList)
{
totalRetailPrice += item.QuantityOnHand * item.RetailPrice;
}
return totalRetailPrice;
}
}
每当我更改列表中任何商品的数量或价格时,我都试图找到一种自动更新此属性 TotalRetailPrice 的方法。我怎样才能做到这一点?现在,使用我的代码,每次我尝试获取此totalRetailPrice 属性时,我都必须遍历该列表并重新计算它。
谢谢!
最佳答案
自界面INotifyPropertyChanged
公开一个名为 PropertyChanged
的事件您可以在“库存”类别中订阅该内容。
您还需要监听列表中更改的事件,因为您需要知道何时添加/删除项目,以便您可以根据需要添加/删除事件处理程序。我建议使用ObservableCollection<T>
因为这支持一些“集合更改”事件。您使用LinkedList<T>
有什么原因吗? ?
例如
public class Inventory
{
private ObservableCollection<Item> _inventoryList = new ObservableCollection<Item>();
public decimal _total;
// You probably want INPC for the property here too so it can update any UI elements bound to it
public decimal Total { get { return _total; } set { _total = value; } }
// Constructor
public Inventory()
{
WireUpCollection();
}
private void WireUpCollection()
{
// Listen for change events
_inventoryList.CollectionChanged += CollectionChanged;
}
private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Check what was added - I'll leave this to you, the e.NewItems are the items that
// have been added, e.OldItems are those that have been removed
// Here's a contrived example for when an item is added.
// Don't forget to also remove event handlers using inpc.PropertyChanged -= Collection_PropertyChanged;
var inpc = e.NewItems[0] as INotifyPropertyChanged;
if(inpc != null)
inpc.PropertyChanged += Collection_PropertyChanged;
}
private void Collection_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
RecalculateTotal();
}
private void RecalculateTotal()
{
// Your original code here which should feed the backing field
}
}
在此处查看 MSDN 文档:
http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx
有关 ObservableCollection<T>
的信息。事件部分就是您所追求的。另请注意,如果您更喜欢语法或想要捕获特定范围内的变量等,您可以使用匿名函数来处理事件。这有助于完全理解它们(不确定 Java 可用什么,因为我还没有真正接触过它)几个 Android 困惑的项目)因此可能值得一读,因为捕获时需要注意一些小警告,但那是另一个故事了!
例如
_inventoryList.CollectionChanged += (o,e) =>
{
// Anonymous method body here
// o = the first param (object sender), e = args (NotifyCollectionChangedEventArgs e)
};
关于C# - 如何利用 "INotifyPropertyChanged"更新集合类中的计算字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20767981/