C# - 如何利用 "INotifyPropertyChanged"更新集合类中的计算字段?

标签 c# collections inotifypropertychanged

我有一个具有两个属性“数量”和“价格”的 Item 类,并实现 INotifyPropertyChanged

public class Item:INotifyPropertyChanged
{
    private event PropertyChangedEventHandler _propertyChanged;
    public event PropertyChangedEventHandler PropertyChanged
    {
        add { _propertyChanged += value; }
        remove { _propertyChanged -= value; }
    }

    void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public int QuantityOnHand
    {
        get
        {
            return this._quantityOnHand;
        }
        set
        {
            if (value > 0)
            {
                this._quantityOnHand = value;
                NotifyPropertyChanged();
            }
            else
            {
                throw new System.ArgumentException("Quantity must be a positive value!");
            }
        }
    }
    .....

}

我有一个名为“Inventory”的商品集合类,其属性为 TotalRetailPrice:

public class Inventory {
private List<Item> _inventoryList = new LinkedList<Item>();
public decimal TotalRetailPrice
    {
        get 
        {
            decimal totalRetailPrice = 0M;
            foreach (var item in _inventoryList)
            {
                totalRetailPrice += item.QuantityOnHand * item.RetailPrice;
            }
            return totalRetailPrice;
        }
    }

每当我更改列表中任何商品的数量或价格时,我都试图找到一种自动更新此属性 TotalRetailPrice 的方法。我怎样才能做到这一点?现在,使用我的代码,每次我尝试获取此totalRetailPrice 属性时,我都必须遍历该列表并重新计算它。

谢谢!

最佳答案

自界面INotifyPropertyChanged公开一个名为 PropertyChanged 的事件您可以在“库存”类别中订阅该内容。

您还需要监听列表中更改的事件,因为您需要知道何时添加/删除项目,以便您可以根据需要添加/删除事件处理程序。我建议使用ObservableCollection<T>因为这支持一些“集合更改”事件。您使用LinkedList<T>有什么原因吗? ?

例如

public class Inventory 
{
    private ObservableCollection<Item> _inventoryList = new ObservableCollection<Item>();

    public decimal _total;
    // You probably want INPC for the property here too so it can update any UI elements bound to it
    public decimal Total { get { return _total; } set { _total = value; } }

    // Constructor     
    public Inventory() 
    {
        WireUpCollection();
    }

    private void WireUpCollection()
    {
        // Listen for change events
        _inventoryList.CollectionChanged += CollectionChanged;
    }

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // Check what was added - I'll leave this to you, the e.NewItems are the items that
        // have been added, e.OldItems are those that have been removed

        // Here's a contrived example for when an item is added. 
        // Don't forget to also remove event handlers using inpc.PropertyChanged -= Collection_PropertyChanged;
        var inpc = e.NewItems[0] as INotifyPropertyChanged;

        if(inpc != null)
          inpc.PropertyChanged += Collection_PropertyChanged;
    }

    private void Collection_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        RecalculateTotal();
    }

    private void RecalculateTotal()
    { 
        // Your original code here which should feed the backing field
    }
}

在此处查看 MSDN 文档:

http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx

有关 ObservableCollection<T> 的信息。事件部分就是您所追求的。另请注意,如果您更喜欢语法或想要捕获特定范围内的变量等,您可以使用匿名函数来处理事件。这有助于完全理解它们(不确定 Java 可用什么,因为我还没有真正接触过它)几个 Android 困惑的项目)因此可能值得一读,因为捕获时需要注意一些小警告,但那是另一个故事了!

例如

_inventoryList.CollectionChanged += (o,e) => 
                                    { 
                                        // Anonymous method body here 
                                        // o = the first param (object sender), e = args (NotifyCollectionChangedEventArgs e)
                                    };

关于C# - 如何利用 "INotifyPropertyChanged"更新集合类中的计算字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20767981/

相关文章:

Java:仅从集合中选择提供类型的元素

c# - 如何在 C# 中将递归对象转换为集合?

javascript - 在 Backbone.js 集合中制作一个模型 'selected' 的最佳方法?

c# - 将 postscript 转换为 jpeg

c# - C# 安装项目的连接 UI.Dialog

c# - ObservableCollection<T> 如何将 INotifyPropertyChanged 实现为 protected ?

c# - 通过 T4 代码生成自动 INotifyPropertyChanged 实现?

.net - 实现 INotifyPropertyChanged 的​​模式?

c# - 查看模型,模型在哪里实现 INotifyPropertyChanged

c# - 多对多按关系计数排序( Entity Framework ,Linq)