ObservableCollection CollectionChanged 在 WPF MVVM 中没有帮助
Posted
技术标签:
【中文标题】ObservableCollection CollectionChanged 在 WPF MVVM 中没有帮助【英文标题】:ObservableCollection CollectionChanged not helpful in WPF MVVM 【发布时间】:2012-04-23 18:01:36 【问题描述】:我正在使用 DataGrid,并使用 ViewModel 中的 ObservableCollection 进行绑定
private ObservableCollection<StockItem> _stockList;
public ObservableCollection<StockItem> StockList
get
return _stockList;
set
_stockList = value;
OnPropertyChanged("StockList");
StockItem 类包含其属性,即 DataGrid 中的列。 DataGrid中有一个名为Amount的列,其值随同一个datagrid的Quantity*Price列发生变化。
我在 ViewModel 中有一个名为 TotalAmount 的属性,它是在 ObservableCollection CollectionChanged 事件中计算的,例如
void OnStockListChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
this.TotalAmount = this.StockList.Sum(t => t.Amount);
只有在将新行添加到包含一些数据的 DataGrid 时,才会在绑定到 TotalAmount 的 TextBox 中更新此值。我希望在数据网格中的金额列更改后立即更新 TotalAmount 的这个 TextBox。
我该怎么做。
StockItem Class
public class StockItem : ObservableObject, ISequencedObject
JIMSEntities dbContext = new JIMSEntities();
public StockItem()
var qs = dbContext.Stocks.Select(s => s.StockName);
_stocks = new CollectionView(qs.ToArray());
_stocks.CurrentChanged += new EventHandler(Stocks_CurrentChanged);
void Stocks_CurrentChanged(object sender, EventArgs e)
if (_stocks.CurrentItem != null)
StockName = _stocks.CurrentItem.ToString();
var qs = (from p in dbContext.Stocks
where p.StockName.Contains(StockName)
select new Unit = p.Unit, UnitPrice = p.UnitPrice ).SingleOrDefault();
if (qs != null)
Unit = qs.Unit;
UnitPrice = (decimal)qs.UnitPrice;
private CollectionView _stocks;
public CollectionView Stocks
get
return _stocks;
set
_stocks = value;
OnPropertyChanged("Stocks");
private int _sNo;
public int SNo
get
return _sNo;
set
_sNo = value;
OnPropertyChanged("SNo");
private string _stockName;
public string StockName
get
return _stockName;
set
_stockName = value;
OnPropertyChanged("StockName");
private decimal _unitPrice;
public decimal UnitPrice
get
return _unitPrice;
set
_unitPrice = value;
OnPropertyChanged("UnitPrice");
OnPropertyChanged("Amount");
private string _unit;
public string Unit
get
return _unit;
set
_unit = value;
OnPropertyChanged("Unit");
private decimal _discount;
public decimal Discount
get
return _discount;
set
_discount = value;
OnPropertyChanged("Discount");
OnPropertyChanged("Amount");
private decimal _quantity;
public decimal Quantity
get
return _quantity;
set
_quantity = value;
OnPropertyChanged("Quantity");
OnPropertyChanged("Amount");
public decimal Amount
get
decimal total = Quantity * (UnitPrice - (UnitPrice * (Discount / 100)));
return total;
public override string ToString()
return StockName;
【问题讨论】:
您的 StockItem 类是否实现了 INotifyPropertyChanged? 使用ObservableCollection that also monitors changes on the elements in collection。 是的,它实现了 INotifyPropertyChangedTotalAmount
长什么样子?
【参考方案1】:
所以,基本上,您所看到的是由于对ObservableCollection
的常见误解。 OC 在其包含的对象发生更改时不会通知。它会在 IT 更改时发出通知(查看 INotifyCollectionChanged)——添加、删除项目等时。
当包含在 OC 中的 StockItem
发生更改时,您想要做的是得到通知。你将不得不做几件事
1) 确保 INotifyPropertyChanged
(你说你已经在做)在你的 StockItem
上实现了
2) 自定义或查找ObservableCollection
的实现,当集合中包含的项目发生更改时通知 (here is one)
【讨论】:
谢谢老兄,那个链接帮助了我。尽管我之前在 *** 中看到过该类,但现在我在我的代码中实现了它 我知道这是在复活一个非常古老的话题,但您是否碰巧将代码包含在“这里有一个”链接中?该网站现已关闭,我仍然很想效仿这个例子。谢谢。 here is one 所指向的链接现在只指向一个简单的“pageok”页面。【参考方案2】:您需要订阅集合中所有项目的PropertyChanged
,以便在任何项目上的Amount
更改时也重新计算值,这有点混乱。某个地方的某个人可能为此编写了实用程序类...
【讨论】:
以上是关于ObservableCollection CollectionChanged 在 WPF MVVM 中没有帮助的主要内容,如果未能解决你的问题,请参考以下文章
Listview 双向绑定与 ObservableCollection
如何将标签的 ItemsControl 绑定到 ObservableCollection
WPF ObservableCollection 异步调用问题