ObservableCollection内部的ObservableCollection不会触发Collection更改事件 [英] ObservableCollection inside ObservableCollection doen't fire Collection changed event

查看:454
本文介绍了ObservableCollection内部的ObservableCollection不会触发Collection更改事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的三天里,我一直面临着一个非常复杂的问题.我正在尝试制作一个接受订单的应用程序,为此,我想拥有一个包含MainCategory项目的ObservableCollection.现在,MainCategory项目包含一个CategoryName和另一个菜式ObservableCollection.这些菜有那些道具:名称,价格和数量.我做了所有这些工作,绑定和所有工作都完美地进行了.

For the last three days I've been facing a quite a composite problem. I am trying to make an order taking app, to do this I wanted to have an ObservableCollection containing MainCategory items. Now the MainCategory items contained a CategoryName and another ObservableCollection of dishes. The dishes have those props: name, price and quantity. I did all this and the bindings and everything works perfectly.

问题出在页面底部(嵌套在Listview内的ListView之外),我想拥有一个TextBlock,其TotalValue每次都需要更改.我正在使用MVVM,并且已将所有INotifyPropertyChanged完成了对道具和CollectionChanged的操作,但这仅在我添加或删除内容时有效.当我在第二个ObservableCollection中更改prop的值时没有.

The problem is at the bottom of the page (outside the ListView which is nested inside a Listview ) I want to have a TextBlock with the TotalValue that needs to change every time The quantity of a dish changes. I am using MVVM and I have done all the INotifyPropertyChanged to the props and the CollectionChanged, but this only works when I add or remove something. Not when I change the value of a prop in the second ObservableCollection.

这是一些代码:

    public class MenuCollection : ObservableCollection<MainCategories>,
INotifyCollectionChanged, INotifyPropertyChanged
{
    public MenuCollection()
    {
        Add(new MainCategories("Category1", false));
        this[0].SubMenuItems.Add(new Dishes("Dish1", 4));

    }
}

 public class MainCategories : MainViewModelBase
{

    public ObservableCollection<Dishes> SubMenuItems{get; set;}  
    public MainCategories(string name, bool visible)
    {
        this.categoryName = name;
        this.visible = visible;
        SubMenuItems = new ObservableCollection<Dishes>();
    }

    public string categoryName;
    public string CategoryName
    {
        get { return categoryName; }
        set
        {
            if (categoryName != value)
            {
                categoryName = value;
                OnPropertyChanged("CategoryName");
            }
        }
    }
    public bool visible;
    public bool Visible
    {
        get { return visible; }
        set
        {
            if (visible != value)
            {
                visible = value;
                OnPropertyChanged("Visible");
            }
        }
    }
}

public class Dishes : MainViewModelBase
{
    public Dishes(string dishName, int price)
    {
        this.dishName = dishName;
        this.dishPrice = price;
        this.quantity = 0;
    }

    private string dishName;
    public string DishName
    {
        get { return dishName; }
        set
        {
            if (dishName != value)
            {
                dishName = value;
                OnPropertyChanged("DishName");
            }
        }
    }
    private int dishPrice;
    public int DishPrice
    {
        get { return dishPrice; }
        set
        {
            if (dishPrice != value)
            {
                dishPrice = value;
                OnPropertyChanged("DishPrice");
            }
        }
    }
    private int quantity;
    public int Quantity
    {
        get { return quantity; }
        set
        {
            if (quantity != value)
            {
                quantity = value;
                OnPropertyChanged("Quantity");
            }
        }
    }

}

我只想找到一种方法,可以在Main可观察集合中的任何变化(例如产品的数量)发生变化时保持我的总价值更新.无论如何,有什么要触发CollectionChanged事件的?

I just want to find a way to keep my total value update when anything changes inside the Main observable collection, like the quantity of a product. is there anyway to fire the CollectionChanged event?

这是用户界面

和没有按钮的早期版本

and an earlier version without the buttons

推荐答案

另一种可能对您有用的选项是我几年前在网上获取的,非常方便.它被称为真正"的可观察集合,不仅会在添加/删除项目时触发事件,而且还会在列表中项目的属性发生更改时触发事件.我还没有在一个集合中的一个集合中尝试过它,但是它应该可以工作

Another option that might work for you is something I picked up online a few years ago and is quite handy. It is call a "Truly" observable collection and will fire events not only when items are added/removed but also when properties on the items within the list change. I havent tried it with a collection within a collection but it should work

public sealed class TrulyObservableCollection<T> : ObservableCollection<T>
where T : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler ItemPropertyChanged;

    public TrulyObservableCollection()
        : base()
    {
        CollectionChanged += new NotifyCollectionChangedEventHandler(TrulyObservableCollection_CollectionChanged);
    }

    public TrulyObservableCollection(IEnumerable<T> pItems)
        : this()
    {
        foreach (var item in pItems)
        {
            this.Add(item);
        }
    }

    void TrulyObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (Object item in e.NewItems)
            {
                (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
            }
        }
        if (e.OldItems != null)
        {
            foreach (Object item in e.OldItems)
            {
                (item as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
            }
        }
    }

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        NotifyCollectionChangedEventArgs a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
        OnCollectionChanged(a);

        if (ItemPropertyChanged != null)
        {
            ItemPropertyChanged(sender, e);
        }
    }
}

这篇关于ObservableCollection内部的ObservableCollection不会触发Collection更改事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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