Обновления ObservableCollection Treeview MVVM - PullRequest
1 голос
/ 16 января 2010

У меня есть древовидная структура, которая связывает множество вложенных 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"  

Когда я изменяю свой Individual.Hours в моем классе ViewModel, я хочу обновить hours ценности в моей команде и отделах тоже.

Я уже использую NotificationProperties для всех моих Hours свойств и ObservableCollections для Teams в Departments и Individuals в Teams.

Спасибо
Mark

Ответы [ 2 ]

4 голосов
/ 16 января 2010

Часы каждого отдела зависят от совокупности часов его команды. Часы каждой команды зависят от совокупности часов ее индивидуума. Таким образом, каждая команда должна прислушиваться к изменениям любого свойства 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 дочернего элемента, поскольку ему сообщается старое значение и новое значение. Таким образом, он знает разницу, применяемую к совокупности.

1 голос
/ 16 января 2010

Я боюсь, что вам придется подробно вызывать уведомление в родительском контейнере ObservableCollection для родителя каждого человека («Team»).

Затем от отдельного родителя установите событие уведомления для родителя («Отдел»).

Team.OnPropertyChanged("Individuals")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...