Search code examples
c#wpfmvvmdata-bindinginotifypropertychanged

Trigger RaisePropertyChanged from a different class


I'm having a class called Mod :

class Mod : INotifyPropertyChanged
{
    private bool serverSideChecked;
    private string name;

    public bool ServerSideChecked
    {
        get => serverSideChecked;
        set
        {
            serverSideChecked = value;
            RaisePropertyChanged("ServerSideChecked");
        }
    }

    public string Name
    {
        get => name;
        set
        {
            name = value;
            RaisePropertyChanged("Name");
        }
    }
}

and another class called Profile that contains a list of Mods

class ServerProfileNew : INotifyPropertyChanged
{
    public int ServerModsChecked { get => Mods.Where(m => m.ServerSideChecked == true).Count(); }

    private List<Mod> _mods = new List<Mod>();
    public List<Mod> Mods
    {
        get => _mods;
        set
        {
            _mods = value;
            RaisePropertyChanged("Mods");
        }
    }
}

Both classes implement INotifyPropertyChanged. I would need ServerModsChecked in Profile to update whenever ServerSideChecked is changed in Mod to have the total count of checked mods in real time.
Is that possible and how to do it ?


Solution

  • In the Mods setter, attach a PropertyChanged event handler to each element in _mods. In that handler, call RaisePropertyChanged("ServerModsChecked");.

    Don't forget to detach the handler from the elements in the current _mods collection before.

    public List<Mod> Mods
    {
        get => _mods;
        set
        {
            if (_mods != null)
            {
                _mods.ForEach(m => m.PropertyChanged -= ModCheckedChanged);
            }
    
            _mods = value;
    
            if (_mods != null)
            {
                _mods.ForEach(m => m.PropertyChanged += ModCheckedChanged);
            }
    
            RaisePropertyChanged("Mods");
        }
    }
    
    private void ModCheckedChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(Mod.ServerSideChecked))
        {
            RaisePropertyChanged(nameof(ServerModsChecked));
        }
    }