2016-12-21 92 views
0

在過去的三天,我一直面臨着相當多的複合問題。我正在嘗試訂購應用程序,爲此我想要一個包含MainCategory項目的ObservableCollection。現在,MainCategory項目包含一個CategoryName和另一個ObservableCollection菜餚。這些菜有道具:名稱,價格和數量。我做了所有這些,綁定和一切都很完美。的ObservableCollection內的ObservableCollection doen't火集合更改事件

問題出在頁面的底部(ListView之外,它嵌套在一個Listview中)我想要一個帶有TotalValue的TextBlock,每次都需要改變盤的數量改變。我正在使用MVVM,並且我已經完成了對道具和CollectionChanged的所有INotifyPropertyChanged,但這隻適用於添加或刪除內容。不是當我改變第二個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"); 
      } 
     } 
    } 

} 

我只是想找到一種方法,讓我的總價值將得到更新主要觀察集合裏面有什麼變化,就像一個產品的數量。無論如何發射CollectionChanged事件?

這是UI this is the UI

和早期版本沒有按鈕 and an earlier version without the buttons

+2

*「的主要觀察集合裏面有什麼變化,就像一個產品的數量時,反正是有火的CollectionChanged事件」 *這已'CollectionChanged'完全沒有關係。它是'INotifyPropertyChanged'。你得到的是一個醜陋的問題。 'MainCategories'需要處理其集合中所有'Dishes'的'PropertyChanged'。當要加總的屬性發生變化時,'MainCategories'重新計算總和並將其分配給一個屬性,也許是'MainCategories.Sum'。 'MenuCollection'與其項目的'Sum'屬性相同。 XAML綁定到MainCollection.Sum –

回答

1

如果需要更新,我會考慮可能不使用可觀察集合時,在收集變化的項目。 Observable集合僅用於記錄何時添加或從集合中刪除項目。

一些我以前做過類似下面的代碼。

在您的MainCategory中,您只會公開IEnumerable<Dish>而不是完整列表。然後,在MainCategory中,您可以創建包裝方法來添加和移除預訂屬性更改通知的菜餚。然後每次更換菜品時,您都可以更新Total的總價值,並通知您的菜品列表已更改。

private List<Dish> _subMenuItems = new List<Dish>(); 
public IEnumerable<Dish> SubMenuItems { get { return _subMenuItems; } } 

public void AddDish(Dish dish) 
{ 
    _subMenuItems.Add(dish); 
    dish.PropertyChanged += dish_PropertyChanged; 
    OnPropertyChanged("SubMenuItems"); 
} 

public void RemoveDish(Dish dish) 
{ 
    if (_subMenuItems.Contains(dish)) 
    { 
     dish.PropertyChanged -= dish_PropertyChanged; 
     _subMenuItems.Remove(dish); 
     OnPropertyChanged("SubMenuItems"); 
    } 
} 

private double _total; 
public double Total 
{ 
    get { return _total; } 
    set 
    { 
     if (_total != value) 
     { 
      _total = value; 
      OnPropertyChanged("Total"); 
     } 
    } 
} 

private void dish_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    Total = getTotal(); 
    // any other aggregate calculations can go here. 
    OnPropertyChanged("SubMenuItems"); 
} 
1

另一種可能適用於您的選擇是幾年前我在網上找到的東西,非常方便。它稱爲「真正」可觀察的集合,不僅會在添加/刪除項目時觸發事件,而且會在列表中的項目屬性發生更改時觸發事件。我還沒有與集合嘗試了一個集合中,但它應該工作

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