Realm对象中OnPropertyChanged无法触发只读属性TotalPrice的Getter
你遇到的核心问题是:Realm对象Group的[Ignored]只读计算属性TotalPrice,在手动调用OnPropertyChanged("TotalPrice")后,属性的Getter未触发,导致UI无法实时刷新;但重新进入页面后计算结果显示正常,说明计算逻辑本身无问题,问题出在属性变更通知的传递或Realm对忽略属性的事件处理上。
1. 修正属性变更通知的调用方式,避免拼写错误
RealmObject的OnPropertyChanged是受保护方法,你封装的ZePropertyChanged可能因硬编码属性名拼写错误导致通知失效,改用nameof关键字确保属性名完全匹配:
// 在Group类中替换原有ZePropertyChanged方法 public void TriggerTotalPriceUpdate() { OnPropertyChanged(nameof(TotalPrice)); }
调用时改为:
[RelayCommand] public async Task RemoveAssociationFromGroup() { SelectedGroup.TriggerTotalPriceUpdate(); }
2. 监听关联对象的属性变化,自动触发TotalPrice更新
由于TotalPrice依赖关联Association对象的Quantity和ProductPricing属性,最可靠的方式是让Group自动监听这些依赖属性的变化,无需手动触发命令:
public class Group : RealmObject { // 你的其他属性定义... public IList<Association> Associations { get; } [Ignored] public string TotalPrice { get { if (Associations.Count == 0 || Associations.Any(asso => asso.ProductPricing is null)) return null; var total = Associations.Sum(asso => asso.ProductPricing!.IsPriced ? asso.ProductPricing.UnitPrice * asso.Quantity : 0.0); return total.ToString("C", CultureInfo.GetCultureInfo("fr-FR")); } } protected override void OnManaged() { base.OnManaged(); // 监听集合增删变化 Associations.CollectionChanged += Associations_CollectionChanged; // 为现有关联对象添加属性监听 foreach (var asso in Associations) { asso.PropertyChanged += Association_PropertyChanged; } } protected override void OnUnmanaged() { base.OnUnmanaged(); // 清理监听,避免内存泄漏 Associations.CollectionChanged -= Associations_CollectionChanged; foreach (var asso in Associations) { asso.PropertyChanged -= Association_PropertyChanged; } } private void Associations_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { // 集合变化时更新TotalPrice if (e.NewItems != null) { foreach (Association asso in e.NewItems) { asso.PropertyChanged += Association_PropertyChanged; } } if (e.OldItems != null) { foreach (Association asso in e.OldItems) { asso.PropertyChanged -= Association_PropertyChanged; } } OnPropertyChanged(nameof(TotalPrice)); } private void Association_PropertyChanged(object sender, PropertyChangedEventArgs e) { // 当关联对象的关键属性变化时,触发TotalPrice更新 var relevantProps = new[] { nameof(Association.Quantity), nameof(Association.ProductPricing), nameof(ProductPricing.IsPriced), nameof(ProductPricing.UnitPrice) }; if (relevantProps.Contains(e.PropertyName)) { OnPropertyChanged(nameof(TotalPrice)); } } }
这样,只要关联的Association对象的Quantity或ProductPricing相关属性变化,或者Associations集合增删元素,TotalPrice会自动触发变更通知,UI实时刷新。
3. 验证UI绑定的正确性
检查页面中TotalPrice的绑定是否指向正确的实例,比如:
<Label Text="{Binding SelectedGroup.TotalPrice}" />
确保ViewModel中的SelectedGroup属性是RealmObject实例,且ViewModel本身实现了INotifyPropertyChanged(如果SelectedGroup是动态赋值的,需确保赋值时触发OnPropertyChanged(nameof(SelectedGroup)))。
4. 兜底方案:强制刷新绑定
如果以上方案仍未生效,可在ViewModel中强制触发SelectedGroup的属性变更通知:
[RelayCommand] public async Task RemoveAssociationFromGroup() { SelectedGroup.TriggerTotalPriceUpdate(); // 强制通知SelectedGroup的变化,触发绑定刷新 OnPropertyChanged(nameof(SelectedGroup)); }
内容的提问来源于stack exchange,提问作者lolveley

