2013-11-26 2 views
2

Я немного борюсь со структурой моего проекта и столкнулся с проблемой, которая волнует меня, демонстрируя, что я все еще не хватает хорошего понимания правильного способа делать что-то.PropertyChanged для дочерних свойств в MVVM

Что я имею в настоящее время:

Программа отображает информацию для судоходства, это основано на общем проект, который содержит проформы, который содержит грузы, которые содержат контейнеры (это упрощено для данного примера)

Так для того, чтобы отслеживать текущие выбранные объекты (проект, проформы и т.д.) у меня есть класс с именем ProjectTree, который выглядит примерно так:

Public class ProjectTree 
{ 
    Public Project SelectedProject { get; set; } 
    Public Proforma SelectedProforma { get; set; } 
    public Shipment SelectedShipment { get; set; } 
} 

снова это упрощается, так как в настоящее время проекта self содержит список Proformas, у меня есть функция в Project под названием LoadProformas(), которая создает новый поток и загружает проформы проекта в ObservableCollection внутри самого проекта (загрузка выполняется с помощью набора IManagers, который обрабатывает всю загрузку данных, сохранение и т. д. .)

Теперь проблема я столкнулась с том, что говорят мои ViewModel ProformaListViewModel имеет доступ к ProjectTree поэтому он может позвонить в LoadProformas() по проекту, я бегу в вопрос о _ProjectTree.SelectedProject.ProformaList привязки данных, как я не буду знать, когда данные фактически были загружены, так как (afaik) NotifyOfPropertyChange не будут проходить через viewmodel в этом сценарии. Теперь я всегда могу использовать EventAggregator и запускать событие, когда данные загружаются (и это то, что я делал в прошлом), однако всякий раз, когда я смотрю на это, кажется немного ... беспорядочным, чтобы запускать несвязанные события из дочерний объект для родителя.

Я пропустил что-то важное в моем понимании здесь? Или использование этого события было бы разумным способом выполнить то, что мне нужно?

EDIT:

Просто, чтобы очистить это вверх, причина им пытаются сделать это, потому что у каждого проекта есть список проформ и каждый проформы список партий и т.д. Первоначально менеджеры обрабатываются списки объектов, а также загрузку и сохранение, но я обнаружил, что, если они полностью отключены, что вызывает проблемы при попытке выполнить работу с проектом на основе его поставок (например)

ответ

0

Каждый из классов viewModel (ваши классы Project, Proforma и shipment могут в этом случае действовать как модель и viewModel) должен реализовать интерфейс INotifyPropertyChanged. Затем ваше представление должно быть привязано непосредственно к объекту SelectedProject.ProformaList. Поскольку список уже есть ObservableCollection, ваше представление будет уведомлено о добавлении или удалении элементов. Затем вам нужно только убедиться, что уведомление PropertyChanged возникает при изменении свойства ProformaList.

Поскольку каждое свойство, связанное в представлении, должно уведомлять об изменениях свойств, каждый уровень дерева данных (Project, Proforma, Shipment) может быть изменен независимо и все еще обновлять представление.

+1

А, я даже не думал об этом, так что спасибо – Ben

3

На мой взгляд, вы не должны использовать никаких объектов Selected... в ваших типах данных/классах моделей ... эти свойства относятся к вашим классам моделей просмотра. Кроме того, если вы фактически не используете объект в своей работе, который называется ProjectTree, я бы не назвал ваш объект тем, что ... просто придерживайтесь реальных имен.

Кроме того, я бы посоветовал не вводить функциональность в классы типов данных ... по моему мнению (по большей части) они должны быть просто контейнерами для данных. Я бы структурировать модель представления, как это (я игнорирую интерфейс INotifyPropertyChanged в этом примере, но вам необходимо правильно реализовать):

public class ProjectViewModel : INotifyPropertyChanged 
{ 
    public ObservableCollection<Project> Projects { get; set; } 
    public Project SelectedProject { get; set; } 
    public ObservableCollection<Proforma> Proformas { get; set; } 
    public Proforma SelectedProforma { get; set; } 
    public ObservableCollection<Shipment> Shipments { get; set; } 
    public Shipment SelectedShipment { get; set; } 

    public void LoadProjects() {} 
    public void LoadProformas() {}    
    public void LoadShipments() {}    
} 

Далее, вы упомянули, что вы используете EventAggregator вместо интерфейса INotifyPropertyChanged ... мне кажется, что вы делаете свою жизнь труднее, чем нужно, так как интерфейс INotifyPropertyChanged может быть использован для этого просто отлично. Внесите его в оба класса типа данных и ваши классы моделей просмотра, а затем они будут работать для каждого объекта.Помните, что вы можете добавить обработчик PropertyChanged в свою модель (ы) просмотра.

+0

Отличный совет здесь. – Gusdor

+0

Несколько комментариев здесь, я не использую его вместо того, чтобы использовать его, а также в зависимости от ситуации. Также причина, по которой мои модели, такие как проект, содержит ObservableCollection, - это проект OWNS Proformas, каждый проект имеет отдельный список проформ, и каждая проформа имеет отдельный список отправок. Иногда мне нужно делать работу над проектом в зависимости от его проформ, например. Следовательно, почему проект содержит список. – Ben

+0

Вы сказали * Я не использую его вместо ... * ... если * 'it' * - это 'EventAggregator', который вы используете *, а также * интерфейс' INotifyPropertyChanged', то он по-прежнему не нужен ... интерфейс «INotifyPropertyChanged» - это все, что вам нужно. Кроме того, я понимаю, что у 'Project' есть коллекция' Proformas' ... коллекция 'Proformas' в моей модели выше была бы полным списком, из которого пользователь мог бы выбрать те, которые нужно добавить к экземпляру' Project'. Аналогично, коллекция «Отгрузки» выше будет содержать все возможные объекты «Отгрузка» для пользователя на выбор. – Sheridan

0

сделали вы пытаетесь вызвать вручную

PropertyChanged (это, новые PropertyChangedEventArgs ("ProformaList"));

после загрузки проектов проформы?

Смежные вопросы