Reputation: 12864
I am using a DataGrid and is bind using an ObservableCollection in the ViewModel
private ObservableCollection<StockItem> _stockList;
public ObservableCollection<StockItem> StockList
{
get
{
return _stockList;
}
set
{
_stockList = value;
OnPropertyChanged("StockList");
}
}
The StockItem class contains its Properties which are the Column in DataGrid. There is a column named Amount in DataGrid whose values changed with Quantity*Price Column of the same datagrid.
I have a Property called TotalAmount in the ViewModel which is calculated in the ObservableCollection CollectionChanged event like
void OnStockListChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
this.TotalAmount = this.StockList.Sum(t => t.Amount);
}
This values is only updated in the TextBox bind to TotalAmount when a new row is added to a DataGrid with some data. I want this TextBox of TotalAmount to be updated as soon as the Amount Column in the datagrid changes.
How can i do this.
StockItem Class
public class StockItem : ObservableObject, ISequencedObject
{
JIMSEntities dbContext = new JIMSEntities();
public StockItem()
{
var qs = dbContext.Stocks.Select(s => s.StockName);
_stocks = new CollectionView(qs.ToArray());
_stocks.CurrentChanged += new EventHandler(Stocks_CurrentChanged);
}
void Stocks_CurrentChanged(object sender, EventArgs e)
{
if (_stocks.CurrentItem != null)
StockName = _stocks.CurrentItem.ToString();
var qs = (from p in dbContext.Stocks
where p.StockName.Contains(StockName)
select new { Unit = p.Unit, UnitPrice = p.UnitPrice }).SingleOrDefault();
if (qs != null)
{
Unit = qs.Unit;
UnitPrice = (decimal)qs.UnitPrice;
}
}
private CollectionView _stocks;
public CollectionView Stocks
{
get
{
return _stocks;
}
set
{
_stocks = value;
OnPropertyChanged("Stocks");
}
}
private int _sNo;
public int SNo
{
get
{
return _sNo;
}
set
{
_sNo = value;
OnPropertyChanged("SNo");
}
}
private string _stockName;
public string StockName
{
get
{
return _stockName;
}
set
{
_stockName = value;
OnPropertyChanged("StockName");
}
}
private decimal _unitPrice;
public decimal UnitPrice
{
get
{
return _unitPrice;
}
set
{
_unitPrice = value;
OnPropertyChanged("UnitPrice");
OnPropertyChanged("Amount");
}
}
private string _unit;
public string Unit
{
get
{
return _unit;
}
set
{
_unit = value;
OnPropertyChanged("Unit");
}
}
private decimal _discount;
public decimal Discount
{
get
{
return _discount;
}
set
{
_discount = value;
OnPropertyChanged("Discount");
OnPropertyChanged("Amount");
}
}
private decimal _quantity;
public decimal Quantity
{
get
{
return _quantity;
}
set
{
_quantity = value;
OnPropertyChanged("Quantity");
OnPropertyChanged("Amount");
}
}
public decimal Amount
{
get
{
decimal total = Quantity * (UnitPrice - (UnitPrice * (Discount / 100)));
return total;
}
}
public override string ToString()
{
return StockName;
}
}
Upvotes: 3
Views: 7922
Reputation: 29196
so, basically, what you are seeing is due to a common mis-conception about ObservableCollection
. OC does NOT notify when objects that it contains are changed. It notifies when IT changes (take a look at INotifyCollectionChanged)--when items are added, removed, etc.
what you want to do is be notified when a StockItem
that is contained in the OC changes. You are going to have to do a couple of things
1) make sure INotifyPropertyChanged
(which you say you are already doing) is implemented on your StockItem
2) customize or find an implementation of ObservableCollection
that will notify when an item contained in the collection changes (here is one)
Upvotes: 6
Reputation: 184296
You need to subscribe to PropertyChanged
of all the items in the collection to also recalculate the value if the Amount
changes on any of the items, it's a bit messy. Someone somewhere might have written utility classes for that...
Upvotes: 1