Как иметь несколько пар "View-ViewModel"? - PullRequest
12 голосов
/ 14 мая 2010

Я создаю приложение, основанное на MVVM-Light. Мне нужно создать несколько экземпляров одного и того же представления, и каждый из них должен связываться со своим собственным ViewModel.

По умолчанию ViewModelLocator реализует ViewModel как синглтоны, поэтому разные экземпляры одного и того же View будут привязаны к одной и той же ViewModel.

Я мог бы создать ViewModel в VMLocator как нестатический объект (так же просто, как вернуть новую VM () ...), но это только частично помогло бы мне. На самом деле, мне все еще нужно следить за открытыми окнами. Тем не менее, каждое окно может открывать несколько других окон (хотя и другого типа). В этой ситуации мне может потребоваться выполнить некоторую операцию с родительским представлением и всеми его дочерними элементами. Например, перед закрытием View P, я могу захотеть закрыть все его дочерние элементы (представление C1, представление C2 и т. Д.).

Следовательно, есть ли простой и легкий способ добиться этого? Или есть ли лучший совет, которому вы бы посоветовали мне следовать?

Заранее благодарим за вашу драгоценную помощь.

Приветствия,
Джанлука.

Ответы [ 3 ]

11 голосов
/ 17 мая 2010

Нет необходимости хранить ViewModel как синглтоны в ViewModelLocator, но это, безусловно, облегчает их поиск , если представление тоже одиночное . Очевидно, что если у вас есть несколько экземпляров одного и того же класса View, у вас будет несколько экземпляров одного и того же класса ViewModel, и он больше не может быть одиночным.

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

Обновление : Зачастую вам даже не нужно отслеживать несколько моделей просмотра. Например, вы можете сделать так, чтобы класс Messenger отправлял сообщение всем экземплярам данного класса viewmodel, используя перегрузку Send. Поэтому, прежде чем использовать словарь для отслеживания виртуальных машин, спросите себя, действительно ли он вам нужен! ;)

Надеюсь, это поможет, Laurent

0 голосов
/ 05 июня 2014

У меня была проблема, отправленная и решенная в этот вопрос SO . Оказалось, что это очень сильно связано с ответом мистера Бюньона (который мне очень помог, спасибо!)

Я обнаружил, что вам вообще не нужно хранить свойство view-model в ViewModelLocator. Просто используйте ServiceLocator, чтобы создать экземпляр с ключом, и в «Службе диалога» передайте ключ на ShowDialog<T>(string key = null).

Также, как уже упоминалось в этой теме, используйте метод Messenger.Default.Send и не забывайте впоследствии вызывать viewModel.Cleanup(), чтобы отменить регистрацию модели представления из Messenger, тем самым предотвращая попытки фантомных моделей представления обрабатывать будущие сообщения, отправленные на все экземпляры типа класса модели представления.

0 голосов
/ 03 апреля 2012

Я использовал систему именования контейнера Unity.

См. " Как различить несколько пар моделей вида / вида, используя контейнер единиц"".

...