如何从Model触发PropertyChanged通知以刷新View?
问题:更新列表对象属性时View不刷新,添加新项却正常
我在更新列表中对象的属性值时,View无法自动刷新;但给列表添加新项时,View能正常刷新。
已实现的基类ViewModel(INotifyPropertyChanged)
public class BaseViewModel : INotifyPropertyChanged { protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion }
业务ViewModel代码
public class SAVSplitViewModel : BaseViewModel { public ObservableCollection<ListItem> Items { get { return primaryBin.Items; } set { primaryBin.Items = value; OnPropertyChanged(); } } public ObservableCollection<ListItem> CurrentItems { get { if (IsPrimaryBin) return primaryBin.Items; else return secondaryBin.Items; } set { if (IsPrimaryBin) primaryBin.Items = value; else secondaryBin.Items = value; } } public ObservableCollection<ListItem> NotCurrentItems { get { if (!IsPrimaryBin) return primaryBin.Items; else return secondaryBin.Items; } set { if (!IsPrimaryBin) primaryBin.Items = value; else secondaryBin.Items = value; } } }
触发属性更新的业务代码
if (Found) { viewModel.IsBusy = true; //检查是否已收到该产品 ListItem origin = viewModel.CurrentItems.FirstOrDefault(i => i.EAN == labelText); updateErp = false; SupplierOrderLineForScan p = viewModel.lines.FirstOrDefault(pr => pr.Ean.Trim() == labelText.Trim()); u = await Common.GetPickingUser(); //检查手推车上是否已有该产品 ListItem bincontentDirection = viewModel.NotCurrentItems.FirstOrDefault(i => i.EAN == labelText); BinContent bincontentOrigin = viewModel.NotCurrentBinContents.Find(s => s.StockId == p.StockId); if (bincontentDirection == default(ListItem)) { bincontentDirection = new ListItem { Quantity = 0 , EAN = origin.EAN, Name = origin.Name}; viewModel.ItemsTransfer.Add(bincontentDirection); } bincontentDirection.Quantity++; origin.Quantity--; }
尝试修改Model类(无效)
public class BaseModel : INotifyPropertyChanged { protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null) { if (EqualityComparer<T>.Default.Equals(backingStore, value)) return false; backingStore = value; onChanged?.Invoke(); OnPropertyChanged(propertyName); return true; } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class ListItem : BaseModel { private int _quantity; public int Quantity { get { return _quantity; } set { SetProperty(ref _quantity, value); } } }
问题原因及解决办法
核心问题:
primaryBin.Items和secondaryBin.Items的类型必须是ObservableCollection<ListItem>,而非普通List<ListItem>。只有ObservableCollection会将集合内对象的PropertyChanged事件传递给绑定系统,普通List做不到这一点。关键检查点:
- 确认
primaryBin和secondaryBin中的Items属性是ObservableCollection<ListItem>类型,比如:public class Bin { public ObservableCollection<ListItem> Items { get; set; } = new ObservableCollection<ListItem>(); } - 调试确认修改
Quantity时,ListItem的SetProperty方法确实触发了OnPropertyChanged,且PropertyChanged事件有订阅者(View的绑定已注册该事件)。 - 检查View的绑定路径是否正确,确保绑定的是
ListItem.Quantity属性。
- 确认
额外注意:你的
CurrentItems和NotCurrentItems的getter直接返回primaryBin或secondaryBin的Items实例,这部分逻辑没问题,但前提是这些实例本身是ObservableCollection。
内容的提问来源于stack exchange,提问作者Elgate
相关产品推荐
相关产品推荐

