ObservableCollection CollectionChanged在WPF MVVM中无用 [英] ObservableCollection CollectionChanged not helpful in WPF MVVM

查看:509
本文介绍了ObservableCollection CollectionChanged在WPF MVVM中无用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using a DataGrid and is bind using an ObservableCollection in the ViewModel

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

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

The StockItem class contains its Properties which are the Column in DataGrid. There is a column named Amount in DataGrid whose values changed with Quantity*Price Column of the same datagrid.

我在ViewModel中有一个称为TotalAmount的属性,该属性是在类似ObservableCollection CollectionChanged事件中计算的

I have a Property called TotalAmount in the ViewModel which is calculated in the ObservableCollection CollectionChanged event like

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

仅当将新行添加到具有某些数据的DataGrid中时,此值才在TextBox绑定中更新为TotalAmount.我希望在datagrid中的金额"列更改时立即更新此TotalAmount的文本框.

This values is only updated in the TextBox bind to TotalAmount when a new row is added to a DataGrid with some data. I want this TextBox of TotalAmount to be updated as soon as the Amount Column in the datagrid changes.

我该怎么做.

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;
    }
}

推荐答案

因此,基本上,您看到的是由于对ObservableCollection的常见误解.当包含它的对象被更改时,OC不会通知.它会通知IT何时发生更改(请查看 INotifyCollectionChanged )-添加,删除项目等时

so, basically, what you are seeing is due to a common mis-conception about ObservableCollection. OC does NOT notify when objects that it contains are changed. It notifies when IT changes (take a look at INotifyCollectionChanged)--when items are added, removed, etc.

您要执行的操作.您将不得不做几件事

what you want to do is be notified when a StockItem that is contained in the OC changes. You are going to have to do a couple of things

1)确保在您的StockItem
上实现了INotifyPropertyChanged(您说已经在做). 2)自定义或找到ObservableCollection的实现,该实现将在集合中包含的项目发生更改时通知(

1) make sure INotifyPropertyChanged (which you say you are already doing) is implemented on your StockItem
2) customize or find an implementation of ObservableCollection that will notify when an item contained in the collection changes (here is one)

这篇关于ObservableCollection CollectionChanged在WPF MVVM中无用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆