Часы каждого отдела зависят от совокупности часов его команды. Часы каждой команды зависят от совокупности часов ее индивидуума. Таким образом, каждая команда должна прислушиваться к изменениям любого свойства Hours
своего индивидуума. При обнаружении он должен вызвать OnPropertyChanged
для своего собственного свойства Hours
. Точно так же каждый Department
должен прослушивать изменения в любом свойстве Hours
своей команды. При обнаружении он должен вызвать OnPropertyChanged
для своего собственного свойства Hours
.
Конечным результатом является то, что изменение часов любого человека (или команды) отражается в родителе.
Псевдо-код, который можно значительно улучшить с помощью рефакторинга, но дает суть ответа:
public class Individual : ViewModel
{
public int Hours
{
// standard get / set with property change notification
}
}
public class Team : ViewModel
{
public Team()
{
this.individuals = new IndividualCollection(this);
}
public ICollection<Individual> Individuals
{
get { return this.individuals; }
}
public int Hours
{
get
{
// return sum of individual's hours (can cache for perf reasons)
}
}
// custom collection isn't strictly required, but makes the code more readable
private sealed class IndividualCollection : ObservableCollection<Individual>
{
private readonly Team team;
public IndividualCollection(Team team)
{
this.team = team;
}
public override Add(Individual individual)
{
individual.PropertyChanged += IndividualPropertyChanged;
}
public override Remove(...)
{
individual.PropertyChanged -= IndividualPropertyChanged;
}
private void IndividualPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Hours")
{
team.OnPropertyChanged("Hours");
}
}
}
}
public class Department : ViewModel
{
public Department()
{
this.teams = new TeamCollection();
}
public ICollection<Team> Teams
{
get { return this.teams; }
}
public int Hours
{
get
{
// return sum of team's hours (can cache for perf reasons)
}
}
// TeamCollection very similar to IndividualCollection (think generics!)
}
Обратите внимание, что если производительность становится проблемой, вы можете иметь саму коллекцию для поддержания общего количества часов. Таким образом, он может выполнять простое добавление всякий раз, когда изменяется свойство Hours
дочернего элемента, поскольку ему сообщается старое значение и новое значение. Таким образом, он знает разницу, применяемую к совокупности.