从另一个 class 触发 RaisePropertyChanged

Trigger RaisePropertyChanged from a different class

我有一个 class 叫 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");
        }
    }
}

和另一个名为 Profile 的 class,其中包含 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");
        }
    }
}

两者 class 都实现了 INotifyPropertyChanged。 每当 Mod 中的 ServerSideChecked 发生变化时,我都需要 Profile 中的 ServerModsChecked 进行更新,以便实时获得已检查模组的总数。
这可能吗?如何做到?

Mods setter 中,将 PropertyChanged 事件处理程序附加到 _mods 中的每个元素。在该处理程序中,调用 RaisePropertyChanged("ServerModsChecked");.

不要忘记之前将处理程序与当前 _mods 集合中的元素分离。

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));
    }
}

Mods 变成只读 ObservableCollection<Mod> 属性 并附加和 attach/detach 事件处理程序 to/from PropertyChanged 任何事件Mod 添加或删除的项目:

class ServerProfileNew : INotifyPropertyChanged
{
    public ServerProfileNew()
    {
        Mods.CollectionChanged += (s, e) => 
        {
            if (e.NewItems != null)
            {
                foreach (object item in e.NewItems)
                {
                    (item as INotifyPropertyChanged).PropertyChanged
                        += new PropertyChangedEventHandler(OnModPropertyChanged);
                }
            }

            if (e.OldItems != null)
            {
                foreach (object item in e.OldItems)
                {
                    (item as INotifyPropertyChanged).PropertyChanged
                        -= new PropertyChangedEventHandler(OnModPropertyChanged);
                }
            }

            RaisePropertyChanged(nameof(ServerModsChecked));
        };
    }

    private void OnModPropertyChanged(object sender, PropertyChangedEventArgs e) =>
        RaisePropertyChanged(nameof(ServerModsChecked));

    public int ServerModsChecked => Mods.Count(m => m.ServerSideChecked);

    public ObservableCollection<Mod> Mods { get; } = new ObservableCollection<Mod>();

    //...
}

这应该使 ServerModsChecked 属性 始终与源集合同步。