我的问题类似于此INotifyPropertyChanged和计算的属性
我重复使用上面例子中的一些代码,因为这样更容易理解发生了什么
假设我从类似的事情开始。请注意,INotifyPropertyChangedBase是我用来实现INotifyAttributeChanged的基类。
public class Order : INotifyPropertyChangedBase
{
private string itemName;
public string ItemName
{
get { return itemName; }
set
{
itemName = value;
}
}
private decimal itemPrice;
public decimal ItemPrice
{
get { return itemPrice; }
set
{
itemPrice = value;
}
}
private int quantity;
public int Quantity
{
get { return quantity; }
set
{
quantity= value;
OnPropertyChanged("Quantity");
OnPropertyChanged("TotalPrice");
}
}
public decimal TotalPrice
{
get { return ItemPrice * Quantity; }
}
}
在生成类似的代码后,我意识到每个订单都可以由多个Items
组成,所以我生成了类似的class : Item
:
public class Item : INotifyPropertyChangedBase
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private decimal price;
public decimal Price
{
get { return price; }
set { price = value; }
}
private int quantity;
public int Quantity
{
get { return quantity; }
set
{
quantity = value;
OnPropertyChanged("Quantity");
}
}
}
然后我将我的Order
类转换为这样。
public class Order : INotifyPropertyChangedBase
{
private ObservableCollection<Item> itemInfo;
public ObservableCollection<Item> ItemInfo
{
get { return itemInfo; }
set
{
itemInfo = value;
OnPropertyChanged("ItemInfo");
OnPropertyChanged("TotalPrice");
}
}
public decimal TotalPrice
{
get
{
Decimal totalPrice;
foreach (Item item in ItemInfo)
{
totalPrice += item.Quantity * item.Price;
}
return totalPrice;
}
}
}
这是通过DataGrid
来实现的。每个Order
是一行。我将列标题绑定到Item.Name
(选项数量有限),并将Item.Quantity
绑定到适当的列单元格。最后一列是TotalPrice
。
以前,当我更改Quantity
时,TotalPrice
会更新。现在,使用Item
的新实现,TotalPrice
将不会在DataGrid
中更新。当我更新Item.Quantity
的实例时,ItemInfo
的setter似乎不会激发。当我更新相应的DataGrid
单元格时,Item.Quantity
上的setter确实会激发。
如何获取要使用嵌套属性(Item
)更新的只读属性(TotalPrice
)的值?
您将不得不像一样监听ItemInfo的CollectionChanged
public class Order : INotifyPropertyChangedBase
{
public Order()
{
ItemInfo =new ObservableCollection<Item>();
ItemInfo.CollectionChanged += ItemInfo_CollectionChanged;
}
void ItemInfo_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged("TotalPrice");
}
private ObservableCollection<Item> itemInfo;
public ObservableCollection<Item> ItemInfo
{
get { return itemInfo; }
set
{
itemInfo = value;
OnPropertyChanged("ItemInfo");
OnPropertyChanged("TotalPrice");
}
}
OR
public class Order : INotifyPropertyChangedBase
{
void ItemInfo_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged("TotalPrice");
}
private ObservableCollection<Item> itemInfo;
public ObservableCollection<Item> ItemInfo
{
get { return itemInfo; }
set
{
if(itemInfo!=null)
itemInfo.CollectionChanged -= ItemInfo_CollectionChanged;
itemInfo = value;
if(itemInfo!=null)
itemInfo.CollectionChanged += ItemInfo_CollectionChanged;
OnPropertyChanged("ItemInfo");
OnPropertyChanged("TotalPrice");
}
}