我有一个Item类,其中包含两个属性“quantity”和“price”,并实现了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属性时,我将不得不浏览列表并重新计算它。
谢谢!
答案 0 :(得分:3)
由于接口INotifyPropertyChanged
公开了一个名为PropertyChanged
的事件,您可以在“库存”类中订阅该事件。
您还需要侦听列表中已更改的事件,因为您需要知道何时添加/删除项目,以便您可以根据需要添加/删除事件处理程序。我建议使用ObservableCollection<T>
,因为它支持一些'收集已更改'事件。你有没有理由使用LinkedList<T>
?
e.g。
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乱七八糟的项目)所以它可能值得一读,因为在捕获时需要注意一些小注意事项,但这是另一个故事!
e.g。
_inventoryList.CollectionChanged += (o,e) =>
{
// Anonymous method body here
// o = the first param (object sender), e = args (NotifyCollectionChangedEventArgs e)
};