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
Author by
Edwin
Updated on July 10, 2020Comments
-
Edwin almost 4 years
I have the following interface:
When an item is added into the
DataGrid
, theTotal column
will update according to (price * quantity), and the totalTextBox
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 totalTextBox
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)); } } }