You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让父类监听自定义子类的属性变更并更新自身属性?

问题描述

我有两个类: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:15:41