Reputation: 302
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 ?
Upvotes: 0
Views: 39
Reputation: 169200
Turn Mods
into a read-only ObservableCollection<Mod>
property and attach and attach/detach event handlers to/from the PropertyChanged
event for any Mod
item that gets added or removed:
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>();
//...
}
This should make the ServerModsChecked
property always in sync with the source collection.
Upvotes: 0
Reputation: 128060
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));
}
}
Upvotes: 1