Ответ 1
На самом деле, правильный способ сделать это - это когда вы сначала создаете ParentVM, вы выполняете итерацию через дочерние элементы переданного родителя, создавая для них ChildVM, а затем добавляйте эти объекты ChildVM в свойство ParentVM ChildVMs. (Некоторые просто назовут это свойство "Дети", но мне лично нравится очищать его от ChildVM, а не от коллекции объектов Child. Просто добавление суффикса "VM" делает это очень понятным.
Затем вам также необходимо прослушать уведомление об изменении в фактической коллекции Parent Children и соответствующим образом обновить вашу коллекцию ChildVM.
Таким образом, у вас есть модель с Parent- > Children- > Child и ViewModel из ParentVM- > ChildVMs- > ChildVM, которая, я считаю, именно то, что вы хотите.
Теперь я также полагаю, что вы должны быть в состоянии разоблачить родителя непосредственно из ParentVM, а также ребенка непосредственно из ChildVM, поскольку ваш пользовательский интерфейс может быть привязан к различным свойствам этих элементов, например, ваше имя свойство выше. Однако пуристы M-V-VM сказали бы, что никогда не делают этого, заявляя, что пользовательский интерфейс никогда не должен знать о модели, потому что, если модель изменяется, вы должны изменить интерфейс. Мой аргумент заключается в том, что если модель меняется, вы все равно должны изменить ViewModel по той же причине. Единственная экономия будет заключаться в том, что если есть несколько просмотров, которые используют один и тот же ViewModel, так как вам просто нужно будет изменить его в одном месте, но в реальности что-то вроде "Имя" не изменит его "имя" от модели до ViewModel, поэтому в этих случаях это не аргумент.
Кроме того, есть накладные расходы на производительность, делая это "пурист" в том, что вы не можете просто делегировать элемент модели, как вы делаете с именем выше, потому что представление никогда не узнает ни о какой модели, сгенерированные изменения свойства Name, если вы также не добавили все дополнительные уведомления об изменении внутри виртуальной машины, то есть теперь у вас есть одно уведомление об изменении в модели, единственной целью которого является запуск второго уведомления об изменении в VM, которое затем уведомляет пользовательский интерфейс. Чистый? Да. Производительность инвазивная? Вы делаете ставку, особенно когда происходят большие изменения, и вы используете интерфейс INotifyPropertyChanged, потому что это означает, что вам нужно выполнять сравнения строк в обработчике изменений, чтобы обнаруживать и делегировать все эти изменения! Однако если вы привязываетесь непосредственно к свойству ParentVM.Parent.Name, у вас уже есть уведомление об изменении из модели, чтобы уведомить пользовательский интерфейс, и вы также сохраняете свою виртуальную машину чистой для вещей, которые являются только VM- или View-specific.
Однако я никогда не делаю ничего в модели, которая доступна только для просмотра. Для меня это то, что для ViewModel. Например, если у детей есть определенный цвет, основанный на перечислении или что-то еще, то для меня это что-то, что происходит в ChildVM, а не в самой модели, и если в модели есть какие-либо свойства, которые диктуют этот цвет, например свойство этого перечисления, в этом случае, да, я бы связал изменения-уведомления из модели внутри ChildVM. (По правде говоря, я могу даже просто сделать это через цветной конвертер в пользовательском интерфейсе напрямую, все еще привязанный к перечислению модели. Это действительно дело в каждом случае.)
НТН,
Марк