-2

I have 2 classes: ParentClass and ChildClass and both are used as datacontext for UserControl with similar hierarchy.

I want to have parent class be notified when it's custom class property has a change in one of it's variables.

    public class ParentClass
    {
        private ChildClass _child;
        private int _value;

        public ChildClass Child
        {
            get
            {
                if (_child == null)
                    Child = new ChildClass();
                return _child;
            }
            set
            {
                _child = value;
                Value = _child.Score;
                OnPropertyChanged(nameof(Child));
            }
        }
        public int Value
        {
            get { return _value; }
            set
            {
                _value = value;
                OnPropertyChanged(nameof(Value));
            }
        }
    }
    public class ChildClass
    {
        private int _score;
        public int Score
        {
            get { return _score; }
            set
            {
                _score = value;
                OnPropertyChanged(nameof(Score));
            }
        }
    }

What I want is that on change of Score, set part of Parent class's Child property is executed and Value updated.

How do I do that?

Edit: Code

PropertyChangedNotify

internal class PropertyChangedNotify : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void OnPropertyChanged(string? property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

Proficiency_Counter - xaml

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text=""/>

    <Viewbox Grid.Column="1">
        <ComboBox ItemsSource="{Binding ProficiencyList}" SelectedItem="{Binding Proficiency}" Margin="1">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <Viewbox>
                        <TextBlock Text="{Binding}"/>
                    </Viewbox>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Viewbox>
</Grid>

Proficiency_Counter_Model - aka ChildClass

internal class Proficiency_Counter_Model: PropertyChangedNotify
{
    #region private
    private int _proficiencyScore;
    private List<char> _proficiencyList;
    private char _proficiency;
    private int _level;
    #endregion
    #region public
    public int ProficiencyScore
    {
        get { return _proficiencyScore; }
        set
        {
            _proficiencyScore = value;
            OnPropertyChanged(nameof(ProficiencyScore));
        }
    }
    public List<char> ProficiencyList
    {
        get
        {
            if (_proficiencyList == null)
            {
                ProficiencyList = new List<char>(); 
                ProficiencyList.Add('U');
                ProficiencyList.Add('T');
                ProficiencyList.Add('E');
                ProficiencyList.Add('M');
                ProficiencyList.Add('L');
                Proficiency = 'U';
            }
            return _proficiencyList;
        }
        set
        {
            _proficiencyList = value;
            OnPropertyChanged(nameof(ProficiencyList));
        }
    }
    public char Proficiency
    {
        get { return _proficiency; }
        set
        {
            _proficiency = value;
            if (Proficiency == 'U')
            {
                ProficiencyScore = 0;
            }
            else if (Proficiency == 'T')
            {
                ProficiencyScore = 2 + _level;
            }
            else if (Proficiency == 'E')
            {
                ProficiencyScore = 4 + _level;
            }
            else if (Proficiency == 'M')
            {
                ProficiencyScore = 6 + _level;
            }
            else if (Proficiency == 'L')
            {
                ProficiencyScore = 8 + _level;
            }
            OnPropertyChanged(nameof(Proficiency));
        }
    }
    public int Level
    {
        get { return _level; }
        set
        {
            _level = value;
            Proficiency = _proficiency;
            OnPropertyChanged(nameof(Level));
        }
    }
    #endregion

}

General_Skill_Counter_Model - aka ParentClass

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();
            }
            return _proficiency;
        }
        set
        {
            _proficiency = value;
            ProficiencyMod = _proficiency.ProficiencyScore;
            OnPropertyChanged(nameof(Proficiency));
        }
    }
    public int ProficiencyMod
    {
        get { return _proficiencyMod; }
        set
        {
            _proficiencyMod = value;
            OnPropertyChanged(nameof(ProficiencyMod));
            OnPropertyChanged(nameof(SkillScore));
        }
    }
    public int ItemMod
    {
        get { return _itemMod; }
        set
        {
            _itemMod = value;
            OnPropertyChanged(nameof(ItemMod));
            OnPropertyChanged(nameof(SkillScore));
        }
    }
    #endregion
}

Proficiency_Counter_Model is set as Proficiency_Counter's DataContext, same for Genereal_Skill_Counter, which I believe is irrelevant to this.

Link
  • 28
  • 5
  • It would be so good if I could copy, paste and run your code. – Enigmativity Sep 26 '22 at 00:19
  • 1
    This is very easy to solve, but I don't want to have to wire up the `OnPropertyChanged` method and `PropertyChanged` event, etc, as I'm sure you have this code already. I'd like to post code that is absolutely relevant to you - and don't want to waste my time. Please post the full code. – Enigmativity Sep 26 '22 at 00:27

1 Answers1

-1

Ok, I figured it out. Instead of notifying the parent, I made the child part of the parent.

Sadly, this only works for single class - It would not work if I had 2 different children of the same class.

Here's the code:

internal class Proficiency_Counter_Model: PropertyChangedNotify
{
    #region private
    protected int _proficiencyScore;
    private List<char> _proficiencyList;
    private char _proficiency;
    protected int _level;
    #endregion
    #region public
    public virtual int ProficiencyScore
    {
        get { return _proficiencyScore; }
        set
        {
            _proficiencyScore = value;
            OnPropertyChanged(nameof(ProficiencyScore));
        }
    }
    public List<char> ProficiencyList
    {
        get
        {
            if (_proficiencyList == null)
            {
                ProficiencyList = new List<char>(); 
                ProficiencyList.Add('U');
                ProficiencyList.Add('T');
                ProficiencyList.Add('E');
                ProficiencyList.Add('M');
                ProficiencyList.Add('L');
                Proficiency = 'U';
            }
            return _proficiencyList;
        }
        set
        {
            _proficiencyList = value;
            OnPropertyChanged(nameof(ProficiencyList));
        }
    }
    public char Proficiency
    {
        get { return _proficiency; }
        set
        {
            _proficiency = value;
            if (Proficiency == 'U')
            {
                ProficiencyScore = 0;
            }
            else if (Proficiency == 'T')
            {
                ProficiencyScore = 2 + _level;
            }
            else if (Proficiency == 'E')
            {
                ProficiencyScore = 4 + _level;
            }
            else if (Proficiency == 'M')
            {
                ProficiencyScore = 6 + _level;
            }
            else if (Proficiency == 'L')
            {
                ProficiencyScore = 8 + _level;
            }
            OnPropertyChanged(nameof(Proficiency));
        }
    }
    public int Level
    {
        get { return _level; }
        set
        {
            _level = value;
            Proficiency = _proficiency;
            OnPropertyChanged(nameof(Level));
        }
    }
    #endregion

}

I made the ProficiencyScore property virtual so that I could override it.

internal class General_Skill_Counter_Model : Proficiency_Counter_Model
{
    #region private
    private string _skillName;
    private int _skillScore;
    private int _abilityMod;
    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 _skillScore; }
        set
        {
            _skillScore = value;
            OnPropertyChanged(nameof(SkillScore));
        }
    }
    public int AbilityMod
    {
        get { return _abilityMod; }
        set
        {
            _abilityMod = value;
            OnPropertyChanged(nameof(AbilityMod));
        }
    }
    public int ItemMod
    {
        get { return _itemMod; }
        set
        {
            _itemMod = value;
            OnPropertyChanged(nameof(ItemMod));
        }
    }
    #endregion

    #region override
    public override int ProficiencyScore
    {
        get { return _proficiencyScore; }
        set
        {
            SkillScore = _skillScore + value - _proficiencyScore;
            _proficiencyScore = value;
            OnPropertyChanged(nameof(ProficiencyScore));
        }
    }
    #endregion
}
Link
  • 28
  • 5