Treeview MVVM ObservableCollection 更新

发布于 2024-08-18 20:04:13 字数 714 浏览 6 评论 0原文

我有一个树视图,它绑定到许多嵌套的 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 属性,并为 Departments中的 Teams 使用 ObservableCollections 团队中的个人

谢谢,
标记

I have a treeview which binds to lots of nested ObservableCollections. Each level of the treeview shows an aggregated sum of all the hours in child items. For example:

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"  

When I modify my Individual.Hours in my ViewModel class i want to update the hours
values in both my team and departments too.

I'm already using NotificationProperties for all my Hours properties, and ObservableCollections for Teams in Departments and Individuals in Teams.

Thanks,
Mark

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨落星ぅ辰 2024-08-25 20:04:13

每个部门的工作时间取决于其团队的工作时间总和。每个团队的时间取决于其个人的总时间。因此,每个团队都应该侦听对其任何个人的 Hours 属性的更改。当检测到时,它应该为其自己的 Hours 属性引发 OnPropertyChanged 。同样,每个Department 都应该侦听其任何团队的Hours 属性的更改。当检测到时,它应该为其自己的 Hours 属性引发 OnPropertyChanged

最终结果是任何个人(或团队)时间的更改都会反映在父级中。

伪代码可以通过重构得到极大的改进,但给出了答案的本质:

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 属性发生变化时,它就可以进行简单的加法,因为它被告知旧值和新值。因此,它知道应用于聚合的差异。

Each department's hours depends on the aggregate of its team's hours. Each team's hours depends on the aggregate of its individual's hours. Thus, each Team should listen for changes to any of its individual's Hours property. When detected, it should raise OnPropertyChanged for its own Hours property. Similarly, each Department should listen for changes to any of its team's Hours property. When detected, it should raise OnPropertyChanged for its own Hours property.

The end result is that changing any individual's (or team's) hours is reflected in the parent.

Pseduo code that can be greatly improved with refactoring but gives the essence of the answer:

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

Note that if performance becomes an issue you can have the collection itself maintain the hour total. That way, it can do a simple addition whenever a child's Hours property changes, because it is told the old value and the new value. Thus, it knows the difference to apply to the aggregate.

別甾虛僞 2024-08-25 20:04:13

我担心您必须在每个个体的父级(“团队”)的父 ObservableCollection 容器上显式调用通知。

然后从单个父级中,为祖级父级(“部门”)设置通知事件。

Team.OnPropertyChanged("Individuals")

I am affraid you will have to explicity call the notification on the parent ObservableCollection container for each individual's parent ('Team').

Then from the individual parent, set notification event for grand parent ('Department').

Team.OnPropertyChanged("Individuals")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文