ObservableCollection.CollectionChanged 未触发
Posted
技术标签:
【中文标题】ObservableCollection.CollectionChanged 未触发【英文标题】:ObservableCollection.CollectionChanged not firing 【发布时间】:2013-03-19 20:33:22 【问题描述】:我有如下界面:
当一个项目被添加到DataGrid
中时,Total column
将根据(价格 * 数量)更新,并且总数 TextBox
也将具有添加的所有行的总数。
但是,当我更改行的数量时,Total column
会更新,但总数 TextBox
不会。
这是我的代码,在此先感谢。
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));
【问题讨论】:
你能展示SaleItem
类吗?
SaleItem 类包含在代码底部附近。
【参考方案1】:
ObservableCollection<SaleItem> items = new ObservableCollection<SaleItem>();
必须是属性
改成
public ObservableCollection<SaleItem> items get;set;
在构造函数中做新的
如果不存在,则让 get 函数创建新对象
你必须有公共的 getter/setter 才能使用绑定
【讨论】:
【参考方案2】:ObservableCollection.CollectionChanged
从集合中添加或删除某些内容而不是正在更新的单个成员时触发。
...
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);
...
这是newSaleItem_PropertyChanged
:
void newSaleItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
setTotal(null, null);
【讨论】:
我明白了。我应该如何解决这个问题? 如果您的SaleItem
实现了INotifyPropertyChanged
,那么您可以为每个SaleItem
使用PropertyChanged
事件。我要编辑我的帖子。【参考方案3】:
您的SaleItem
必须实现INotifyPropertyChanged
然后您将拥有PropertyChanged
事件并且您可以订阅它。使用 INotifyPropertyChanged 将有利于绑定。
【讨论】:
以上是关于ObservableCollection.CollectionChanged 未触发的主要内容,如果未能解决你的问题,请参考以下文章