2016-12-21 29 views
0

私はかなり複雑な問題に直面しています。私はアプリケーションを取る注文をしようとしている、これを行うには、私はObservableCollection MainCategoryの項目を含むようにしたい。現在、MainCategory項目にはCategoryNameとObservableCollectionが含まれています。料理には名前、価格、数量といった小道具があります。私はこれをすべて行い、バインディングとすべてが完璧に機能します。ObservableCollection内のObservableCollectionは発生しません。コレクションの変更イベント

問題はページ下部(ListView内にネストされているListViewの外側)です。毎回変更する必要のあるTotalValueをTextBlockに追加したいと思います。私はMVVMを使用していて、私はすべてのINotifyPropertyChangedを小道具とCollectionChangedに行っていますが、これは何かを追加または削除するときにのみ機能します。 2番目の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イベントを発生させるにはどうしますか?

この

は、ボタン and an earlier version without the buttons

+2

*それは持っている*「製品の数量などの主な観測可能なコレクション内の何が変化し、。て、CollectionChangedイベントを発生するとにかくがある場合」 'CollectionChanged'では何もしません。それは 'InotifyPropertyChanged'です。あなたが持っているものは醜い問題です。 'MainCategories'はコレクション内のすべての' Dishes'に対して 'PropertyChanged'を処理する必要があります。合計されるプロパティが変更されると、 'MainCategories'はその合計を再計算し、それをプロパティに代入します。おそらく' MainCategories.Sum'です。 'MenuCollection'はアイテムの' Sum'プロパティと同じことをします。 XAMLはMainCollection.Sumにバインドします。 –

答えて

1

更新を必要とする場合、私はおそらく、観察コレクションを使用していない検討することなく、UI this is the UI

およびそれ以前のバージョンであるとき、コレクションの変更内の項目。観察可能なコレクションは、アイテムがコレクションに追加されたり削除されたりしたときにのみ有効です。

私が以前に行ったことは、以下のコードに似ています。

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

あなたのために役立つ別のオプションは、私が数年前にオンラインで手にしたもので、とても便利です。 「真に」観察可能なコレクションを呼び出し、アイテムが追加/削除されたときだけでなく、リスト内のアイテムのプロパティが変更されたときにもイベントを発生させます。私は、コレクション内のコレクションでそれを試してみましたhaventはそれが動作するはず

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); 
     } 
    } 
} 
関連する問題