2017-01-20 7 views
1

У меня есть классы, A, B, C, DMVVM: Неплотно связь ViewModels

А имеет ссылку на Е и В и к списку C и D.

В AViewModel они подвергаются в дереве.

Вид для A выглядит как на картинке.

enter image description here

Когда узел выбран вид корреспондентский должен быть отображен.

Существует ViewModels для E, B, C и D

Мой вопрос заключается в следующем:

Например Е выбранный узел. Я храню его в AViewModel как «object SelectedItem». Каков наилучший способ создания EViewModel в связном виде, так что я не хочу ссылаться на EViewModel в AViewModel.

Update:

Я думал об одном решения, но я никогда не видел, что в других местах:

Например, я мог выставить только мой Pocos (B, C, D, E) из AViewModel. И в XAML я мог напрямую связать ContentControl с этими объектами. С конвертером я мог бы иметь BViewModel, когда я привязываюсь к B и так далее.

+0

Можете ли вы разместить свой xaml, чтобы нам не пришлось изобретать велосипед? – lokusking

ответ

0

Если ваш A View отображает «список», плюс выбранный вид, вполне приемлемо иметь ссылку EViewModel в AViewModel. ViewModels могут быть «отражением» представлений. Поэтому, если представление A будет содержать EView, AViewModel может содержать EViewModel. Вы просто вставляете свои модели просмотра, чтобы создать то же дерево, что и на уровне представления.

К тому же, что бы я сделал, это не ссылка E или B, ... в AViewModel, а ссылка только EViewModel, BViewModel, ... Поэтому в списке AView не отображаются классы моделей, но классы ViewModel. Ваш SelectedItem набирается как ViewModel, и вы можете напрямую привязать часть просмотра «Display» к SelectedItem. Затем вы можете использовать правильный DataTemplate на уровне представления, чтобы отобразить соответствующий вид. Надеюсь, это поможет.

+0

Это то, что я делаю сейчас :) Но я всегда чувствовал, что это можно сделать лучше. – jannagy02

1

Общим и общепринятым способом общения между моделями просмотра и другими компонентами в связном виде в приложении MVVM будет использование агрегатора событий или мессенджера. Для получения дополнительной информации см. Следующие ссылки.

Использование событий шаблон агрегатор для связи между видом модели:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

MVVM - Коммуникатор и вид услуг в MVVM:https://msdn.microsoft.com/en-us/magazine/jj694937.aspx.

Другим вариантом было бы использовать общий сервис, который вы впрыснуть модели просмотра с: https://social.msdn.microsoft.com/Forums/en-US/22907a0f-d805-4195-8272-7c284b72d2ee/example-of-using-shared-services-prism?forum=wpf

Используя агрегатор событий, мессенджер или общая служба означает, что вы можете удалить все ссылки между вид модели классов.

Вместо классов модели представления, имеющих сильные ссылки друг на друга взад и вперед, каждая модель просмотра знает только об одном агрегаторе событий/мессенджере/совместно используемой службе и сообщает только об этом. Модель просмотра A может отправлять любое количество сообщений, которые могут отображать любые другие модели просмотра, чтобы слушать и обрабатывать внутренне.

Мой вопрос о наилучшей практике на тему создания экземпляра ViewModel, не имея тесную связь, а не о связи между слабо связанным ViewModels

Созданием экземпляра другого видом модели, не создавая связывание струн невозможно. Если одна модель представления создает экземпляр другой модели представления, они по определению сильно связаны. Чтобы предотвратить это можно впрыснуть модель представления с типом интерфейса, что другой вид модели орудия и т.д .:

public ViewModelB(IViewModelA viewModelA) 
{ 
    //... 
} 

Тогда ViewModelB зависит от типа интерфейса, а не конкретной реализации ViewModelA. Это немного лучше, чем делать что-то вроде этого, потому что тогда ViewModelA и ViewModelB всегда будет - как уже упоминалось выше - сильно связаны друг с другом:

public ViewModelB() 
{ 
    _viewModelA = new ViewModellA(); 
} 

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

+0

Мой вопрос касается лучших практик по теме создания экземпляра ViewModel без подключения к тигту, а не связи между слабо связанными ViewModels. – jannagy02

+0

Это невозможно. Если одна модель представления создает экземпляр другой модели представления, они по определению сильно связаны. См. Мой отредактированный ответ для получения дополнительной информации. – mm8

+0

@ jannagy02 Используйте заводский метод и верните интерфейс (экземпляр). Или используйте контейнер DI, такой как Prism, - вы запрашиваете тип (используйте интерфейсы) и получаете конкретный тип обратно. Но для того, что вы указали, это похоже на то, что B, C, D и E - все POCOs (которые могут быть обернуты собственными моделями просмотра) - все в порядке, чтобы AViewModel знал о них, потому что его задача - формировать, преобразовывать и представлять данные в вид. – slugster

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