我的问题类似于此INotifyPropertyChanged and calculated property
我正在重复使用上面示例中的一些代码,因为它更容易理解正在发生的事情。
假设我从类似的东西开始。请注意,INotifyPropertyChangedBase是我用来实现INotifyPropertyChanged的基类。
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
。
以前,TotalPrice
会在我更改Quantity
时更新。现在,使用Item
的新实施,TotalPrice
中的DataGrid
将不会更新。当我更新ItemInfo
的实例时,似乎Item.Quantity
的setter不会触发。当我更新相应的Item.Quantity
单元格时,DataGrid
上的setter会触发。
如何使用嵌套属性(TotalPrice
)获取只读属性(Item
)的值?
答案 0 :(得分:2)
您必须收听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");
}
}