ObservableCollection CollectionChanged对WPF MVVM没有帮助

时间:2012-04-23 18:01:37

标签: c# wpf mvvm viewmodel observablecollection

我正在使用DataGrid并使用ViewModel中的ObservableCollection进行绑定

private ObservableCollection<StockItem> _stockList;
public ObservableCollection<StockItem> StockList
{
    get
    {
        return _stockList;
    }
    set
    {
        _stockList = value;
        OnPropertyChanged("StockList");                
    }
}

StockItem类包含其属性,即DataGrid中的列。 DataGrid中有一个名为Amount的列,其值已更改为同一数据网格的Quantity * Price Column。

我在ViewModel中有一个名为TotalAmount的属性,它在ObservableCollection CollectionChanged事件中计算,如

void OnStockListChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    this.TotalAmount = this.StockList.Sum(t => t.Amount);
}

只有在使用某些数据向DataGrid添加新行时,才会在TextBox绑定到TotalAmount时更新此值。一旦数据网格中的数量列发生变化,我希望更新TotalBmount的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;
    }
}

2 个答案:

答案 0 :(得分:7)

所以,基本上,你所看到的是由于对ObservableCollection的常见错误概念。 OC不会在其包含的对象发生更改时通知。它通知IT何时发生变化(查看INotifyCollectionChanged) - 添加,删除项目等等。

当OC中包含的StockItem发生变化时,会通知您要执行的操作。你将不得不做几件事

1)确保在INotifyPropertyChanged上实施StockItem(您说您已经在做) 2)自定义或查找ObservableCollection的实施,该实施将在集合中包含的项目发生变化时发出通知(here is one

答案 1 :(得分:1)

如果PropertyChanged更改了任何项目,您需要订阅集合中所有项目的Amount以重新计算值,这有点混乱。某个人可能会为此编写实用程序类......