ObservableCollection.CollectionChanged not firing

21,992

Solution 1

ObservableCollection.CollectionChanged fire when something is added or deleted from the collection not the individual members being update.

...
else 
{
    txtItemID.Text = "";
    lblErr.Content = "";
    SaleItem newItem = new SaleItem() {
                    Num = items.Count + 1,
                    ItemID = itm.ItemID,
                    Name = itm.Name,
                    Price = decimal.Round(itm.Price, 2, MidpointRounding.AwayFromZero),
                    Quantity = 1 };
     newItem.PropertyChanged += 
             new PropertyChangedEventHandler(newSaleItem_PropertyChanged);

    items.Add(newItem);
 }
 ...

And this is the newSaleItem_PropertyChanged:

void newSaleItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    setTotal(null, null);
}

Solution 2

 ObservableCollection<SaleItem> items = new ObservableCollection<SaleItem>();

must be a propery

change it to

public ObservableCollection<SaleItem> items {get;set;}

and do the new in the constructor

or make the get function create new object if one doesn't exist

you must have public getter/setter to use binding

Share:
21,992
Edwin
Author by

Edwin

Updated on July 10, 2020

Comments

  • Edwin
    Edwin almost 4 years

    I have the following interface:

    DataGrid

    When an item is added into the DataGrid, the Total column will update according to (price * quantity), and the total TextBox will also have the total of all the rows added.

    However, when I change the quantity of a row, the Total column updates, but the total TextBox does not.

    Here is my code, thanks in advance.

     public partial class pgCheckout : Page {
    
        ObservableCollection<SaleItem> items = new ObservableCollection<SaleItem>();
    
        public pgCheckout() {
            InitializeComponent();
            dgItems.ItemsSource = items;
            dgItems.Loaded += SetMinWidths;
            items.CollectionChanged += setTotal;
        }
    
        public void setTotal(object source, EventArgs e) {
            decimal total = 0;
            foreach(SaleItem i in items) {
                total += i.Total;
            }
    
            txtTotal.Text = total.ToString();
        }
    
    
        public void SetMinWidths(object source, EventArgs e) {
            foreach (var column in dgItems.Columns) {
                if (column.DisplayIndex != 0) {
                    column.MinWidth = column.ActualWidth;
                    column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
                }
            }
        }
    
        private void btnRemove_Click(object sender, RoutedEventArgs e) {
            items.RemoveAt(dgItems.SelectedIndex);
        }
    
        private void btnAdd_Click(object sender, RoutedEventArgs e) {
            bool exist = false;
            foreach (SaleItem i in items) {
                if (i.ItemID.Equals(txtItemID.Text))
                    exist = true;
            }
    
            if (exist) {
                lblErr.Content = "Item already exist";
                txtItemID.Text = "";
            }
    
            else {
    
                using (var db = new PoSEntities()) {
                    var query = from i in db.Items
                                where i.ItemID.Equals(txtItemID.Text.Trim())
                                select i;
                    var itm = query.FirstOrDefault();
                    if (itm == null) {
                        lblErr.Content = "Invalid Item";
                        txtItemID.Text = "";
                    }
                    else {
                        txtItemID.Text = "";
                        lblErr.Content = "";
                        items.Add(new SaleItem() {
                            Num = items.Count + 1,
                            ItemID = itm.ItemID,
                            Name = itm.Name,
                            Price = decimal.Round(itm.Price, 2, MidpointRounding.AwayFromZero),
                            Quantity = 1,
                        });
                    }
                }
            }
        }
    
        private void txtItemID_KeyUp(object sender, KeyEventArgs e) {
            if (e.Key == System.Windows.Input.Key.Enter) {
                btnAdd_Click(txtItemID, e);
            }
        }
    }
    
    class SaleItem : INotifyPropertyChanged {
        public int Num { get; set; }
        public string ItemID { get; set; }
        public string Name { get; set; }
    
        private decimal price;
        public decimal Price {
            get { return price; }
            set {
                this.price = value;
                OnPropertyChanged("Total");
            }
        }
        public int quantity;
        public int Quantity {
            get { return quantity; }
            set {
                this.quantity = value;
                OnPropertyChanged("Total");
            }
        }
    
        public decimal Total {
            get { return decimal.Round(Price * Quantity, 2, MidpointRounding.AwayFromZero); }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName) {
            var handler = PropertyChanged;
            if (handler != null) {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }