【问题标题】:Trigger RaisePropertyChanged from a different class从不同的类触发 RaisePropertyChanged
【发布时间】:2020-10-28 22:49:24
【问题描述】:

我有一个名为 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 的类,其中包含一个 Mod 列表

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

这两个类都实现了 INotifyPropertyChanged。 我需要Profile 中的ServerModsChecked 来更新ServerSideCheckedMod 中的更改,以便实时查看已检查模块的总数。
这可能吗?怎么做?

【问题讨论】:

  • Mods 设置器中,将 PropertyChanged 事件处理程序附加到 _mods 中的每个元素。在该处理程序中,调用RaisePropertyChanged("ServerModsChecked");。之前不要忘记将处理程序与当前_mods 集合中的元素分离。
  • 我实际上是在将 Mod 添加到列表时尝试附加 PropertyChanged,但它每次触发大约 4 次...我会尝试你的 dais 但我不完全理解你所说的分离是什么意思来自 _mods 的处理程序
  • 请看答案。

标签: c# wpf mvvm data-binding inotifypropertychanged


【解决方案1】:

Mods 转换为只读ObservableCollection&lt;Mod&gt; 属性,并为添加或删除的任何Mod 项目附加和附加/分离事件处理程序到/从PropertyChanged 事件:

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 属性始终与源集合同步。

【讨论】:

    【解决方案2】:

    Mods 设置器中,将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));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 2019-05-05
      • 2012-06-22
      相关资源
      最近更新 更多