我有一个树视图,它绑定了许多嵌套的ObservableCollections。树视图的每个级别显示子项中所有小时的总和。例如:
Department 1, 10hrs
├ Team 10, 5hrs
│ ├ Mark, 3hrs
│ └ Anthony, 2hrs
└ Team 11, 5hrs
├ Jason, 2hrs
├ Gary, 2hrs
└ Hadley, 1hrs
Department 2, 4hrs
├ Team 20, 3hrs
│ ├ Tabitha, 0.5hrs
│ ├ Linsey, 0.5hrs
│ └ Guy, 2hrs
└ Team 11, 1hr
└ "Hadley, 1hr"
当我在ViewModel类中修改Individual.Hours
时,我想要更新hours
我的团队和部门也都有价值观。
我已经使用NotificationProperties
用于我的所有Hours
属性,Teams
用于Departments
和Individuals
Teams
的ObservableCollections。
谢谢,
标记
答案 0 :(得分:4)
每个部门的工作时间取决于团队工作时间的总和。每个团队的工作时间取决于其个人工作时间的总和。因此,每个团队都应该倾听对其任何个人Hours
财产的更改。检测到后,它应该为自己的OnPropertyChanged
属性引发Hours
。同样,每个Department
都应该监听其团队Hours
任何属性的更改。检测到后,它应该为自己的OnPropertyChanged
属性提升Hours
。
最终结果是,改变任何个人(或团队)的时间会反映在父母的身上。
Pseduo代码可以通过重构大大改进,但给出了答案的本质:
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
属性发生变化,就可以进行简单的添加,因为它会告诉旧值和新值。因此,它知道应用于聚合的差异。
答案 1 :(得分:1)
我很害怕你必须明确地在父ObservableCollection容器上为每个人的父母('团队')调用通知。
然后从个别父母那里为祖父母('部门')设置通知事件。
Team.OnPropertyChanged("Individuals")