ObservableCollection在WPF MVVM中的CollectionChanged事件不够有用

3

我正在使用一个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在datagrid中的Amount列更改时立即更新。

我该如何做到这一点。

StockItem类

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接口吗? - Joel Lucsy
是的,它实现了INotifyPropertyChanged。 - Kishore Kumar
TotalAmount 是什么样子? - Jake Berger
2个回答

6

所以,基本上,你看到的是关于ObservableCollection的一个常见误解。 OC不会在其包含的对象更改时发出通知。 它会在它自己更改时发出通知(参见INotifyCollectionChanged),即添加、删除等操作。

你想要的是,在包含的OC中的StockItem发生变化时得到通知。您需要执行以下几个步骤:

1)确保已在StockItem上实现了INotifyPropertyChanged(你说你已经实现了)
2)定制或找到一个ObservableCollection的实现,当集合中的项发生更改时发出通知(这里有一个


谢谢老兄,那个链接对我很有帮助。虽然我之前在StackOverFlow上看过那个类,但现在我已经在我的代码中实现了它。 - Kishore Kumar
3
我知道这是重新讨论一个旧话题,但你是否有那个“here is one”链接中包含的代码?该网站现在已经关闭,我仍然非常想按照示例操作。谢谢。 - Anya Hope
_here指向的链接现在只能跳转到一个简单的页面,上面只显示“pageok”。 - Rod

1

您需要订阅集合中所有项的PropertyChanged事件,以便在任何项的Amount更改时也重新计算值,这有点混乱。某个地方可能已经编写了实用程序类来处理这个问题...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接