基于MVVM Community Toolkit:多属性Patient模型保存按钮状态控制
针对你的场景,无需为每个属性编写重复代码,以下两种简洁方案可实现需求:
方案一:订阅Patient的PropertyChanged事件(推荐)
利用MVVM Community Toolkit特性,让ViewModel统一监听Patient实例的所有属性变更,触发SaveButton启用逻辑:
步骤1:修改ViewModel中的Patient字段为ObservableProperty
将私有patient字段改为带[ObservableProperty]特性的属性,通过自动生成的partial方法监听实例切换并订阅事件:
public partial class PatientViewModel : ObservableObject { private bool _patientPropertyChanged = false; // 替换原私有字段为ObservableProperty [ObservableProperty] private Patient? _patient; // ... 其他原有代码不变 // MVVM Toolkit自动生成的partial方法,处理Patient实例变更 partial void OnPatientChanged(Patient? oldValue, Patient? newValue) { // 取消旧实例的事件订阅 oldValue?.PropertyChanged -= Patient_PropertyChanged; // 订阅新实例的事件 newValue?.PropertyChanged += Patient_PropertyChanged; // 重置变更标记并更新按钮状态 _patientPropertyChanged = false; SaveChangesCommand.NotifyCanExecuteChanged(); } // 统一处理Patient所有属性变更 private void Patient_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { // 排除计算属性(如Crucials、Age),只监听实体可编辑属性 if (e.PropertyName != nameof(Patient.Crucials) && e.PropertyName != nameof(Patient.Age)) { _patientPropertyChanged = true; SaveChangesCommand.NotifyCanExecuteChanged(); } } // ... 其他原有代码不变 }
步骤2:确保Patient自动实现INotifyPropertyChanged
由于你已使用[ObservableProperty]特性,MVVM Toolkit会自动为Patient类生成INotifyPropertyChanged实现,无需额外修改Patient代码。
方案二:在Patient类内部封装变更标记
将变更逻辑封装在Patient内部,添加IsDirty属性统一标记状态:
修改Patient类
public partial class Patient : GenericEntity { private bool _isDirty; public bool IsDirty { get => _isDirty; private set => SetProperty(ref _isDirty, value); } public Patient() { // 订阅自身属性变更事件 PropertyChanged += Patient_PropertyChanged; } private void Patient_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { // 排除计算属性,只标记实体属性变更 if (e.PropertyName != nameof(Crucials) && e.PropertyName != nameof(Age)) { IsDirty = true; } } // ... 原有属性代码不变 }
修改ViewModel的启用逻辑
// 更新CanSaveChanges判断逻辑 private bool CanSaveChanges() => Patient?.IsDirty ?? false; // 在Patient实例切换时重置标记 partial void OnPatientChanged(Patient? oldValue, Patient? newValue) { newValue?.IsDirty = false; SaveChangesCommand.NotifyCanExecuteChanged(); }
补充说明
- 两种方案均避免了重复代码,一次性监听所有属性变更
- 可根据需求调整排除的属性(如无需触发保存的计算属性)
- 保存成功后需重置变更标记:在
SaveChanges方法末尾添加_patientPropertyChanged = false; SaveChangesCommand.NotifyCanExecuteChanged();(方案一)或Patient.IsDirty = false;(方案二)
内容的提问来源于stack exchange,提问作者NAngelGr
相关产品推荐
相关产品推荐

