如何让父类监听自定义子类的属性变更并更新自身属性?
问题描述
我有两个类:General_Skill_Counter_Model(父类)和Proficiency_Counter_Model(子类),分别作为层级UserControl的DataContext。需求是:当子类的ProficiencyScore属性变化时,父类能收到通知,更新ProficiencyMod和SkillScore属性。
解决方案
核心思路是让父类订阅子类的PropertyChanged事件,监听ProficiencyScore的变化,然后触发父类自身的属性更新逻辑。具体修改如下:
步骤1:修改父类的Proficiency属性
在父类的Proficiency属性中,需要完成三个关键操作:给新的子类实例订阅事件、取消旧子类实例的事件订阅(避免内存泄漏)、在事件处理方法中响应ProficiencyScore的变化。
修改后的General_Skill_Counter_Model代码:
internal class General_Skill_Counter_Model: PropertyChangedNotify { #region private private string _skillName; private int _abilityMod; private Proficiency_Counter_Model _proficiency; private int _proficiencyMod; private int _itemMod; #endregion #region public public string SkillName { get { if (_skillName == null) SkillName = "Lorem Impsum"; return _skillName; } set { _skillName = value; OnPropertyChanged(nameof(SkillName)); } } public int SkillScore { get { return (AbilityMod + Proficiency.ProficiencyScore + ItemMod); } } public int AbilityMod { get { return _abilityMod; } set { _abilityMod = value; OnPropertyChanged(nameof(AbilityMod)); OnPropertyChanged(nameof(SkillScore)); } } public Proficiency_Counter_Model Proficiency { get { if (_proficiency == null) { _proficiency = new Proficiency_Counter_Model(); // 给新创建的子类实例订阅PropertyChanged事件 _proficiency.PropertyChanged += Proficiency_PropertyChanged; } return _proficiency; } set { // 取消旧子类实例的事件订阅,防止内存泄漏 if (_proficiency != null) { _proficiency.PropertyChanged -= Proficiency_PropertyChanged; } _proficiency = value; // 给新的子类实例订阅事件 if (_proficiency != null) { _proficiency.PropertyChanged += Proficiency_PropertyChanged; // 初始化ProficiencyMod的值 ProficiencyMod = _proficiency.ProficiencyScore; } OnPropertyChanged(nameof(Proficiency)); } } private void Proficiency_PropertyChanged(object? sender, PropertyChangedEventArgs e) { // 检测是否是ProficiencyScore属性发生变化 if (e.PropertyName == nameof(Proficiency_Counter_Model.ProficiencyScore)) { var proficiencyModel = sender as Proficiency_Counter_Model; if (proficiencyModel != null) { ProficiencyMod = proficiencyModel.ProficiencyScore; // 触发SkillScore的变更通知,让UI更新 OnPropertyChanged(nameof(SkillScore)); } } } public int ProficiencyMod { get { return _proficiencyMod; } set { _proficiencyMod = value; OnPropertyChanged(nameof(ProficiencyMod)); } } public int ItemMod { get { return _itemMod; } set { _itemMod = value; OnPropertyChanged(nameof(ItemMod)); OnPropertyChanged(nameof(SkillScore)); } } #endregion }
关键修改点说明
- 在
Proficiency的getter中,创建子类实例后立即订阅PropertyChanged事件,确保从实例创建开始就能监听其属性变化 - 在setter中,先取消旧实例的事件订阅再给新实例订阅,避免无效的事件监听导致内存泄漏
- 新增
Proficiency_PropertyChanged方法,专门处理子类的属性变化:当检测到ProficiencyScore变化时,更新ProficiencyMod并触发SkillScore的变更通知 - 无需触发父类
Proficiency属性的setter(因为子类实例本身没有被替换,只是内部属性变化),直接更新父类相关属性更高效合理
内容的提问来源于stack exchange,提问作者Link
相关产品推荐
相关产品推荐

