Как ViewModel может узнать, когда обновляются данные в службе?

StackOverflow https://stackoverflow.com/questions/645557

  •  22-07-2019
  •  | 
  •  

Вопрос

В моем приложении у меня есть несколько ViewModels, которые имеют один сервис (репозиторий, DAO, что угодно), давайте назовем его WidgetService Виджетсервис, вводимый в них.

Допустим, что одна из этих ViewModels представляет собой список всех пользовательских виджетов.Другим может быть ViewModel для редактирования / создания одного из этих виджетов.

Пользователь может просмотреть список виджетов в WidgetListView (Список виджетов) подкрепленный WidgetListViewModel - Модель просмотра виджетов и нажмите кнопку, чтобы добавить новый виджет.Чтобы создать этот новый виджет, необходимо CreateWidgetViewModel Создать видовую модель создается new'd и вводится в DataContext некоторого UserControl / Window таким образом, благодаря магии DataTemplates, отображающих CreateWidgetViewModel Создать видовую модель в CreateWidgetView Создать виджет просмотра.Кроме того, обновление системы CreateWidgetViewModel Создать видовую модель не обязательно происходит в рамках WidgetListViewModel - Модель просмотра виджетов.

Когда WidgetListViewModel - Модель просмотра виджетов он был введен вместе с экземпляром WidgetService Виджетсервис .Тот Самый CreateWidgetViewModel Создать видовую модель был введен этот самый WidgetService Виджетсервис пример.

Теперь, когда пользователь нажимает Сохранить в CreateWidgetView Создать виджет просмотра тот самый Сохранить метод на основе WidgetService Виджетсервис будет вызван, и виджет будет сохранен.Теперь этот WidgetListViewModel - Модель просмотра виджетов необходимо получить уведомление о появлении нового виджета для отображения!

Длительное накопление приводит к этому вопросу:Как мне позволить WidgetListViewModel - Модель просмотра виджетов знаете, что для этого нужно отобразить новый виджет?

Я видел Видео в которой парень из Microsoft делает подобные вещи, используя событие в службе, на которую подписана ViewModel.Однако недостатком этого является то, что если сервис переживет viewmodel, то viewmodel не получит GC'd, пока сервис не будет GC'd .Я мог бы добавить IDisposable в ViewModel.Но тогда, когда / как вызвать Dispose, когда ViewModel представлен только в пользовательском интерфейсе через DataTemplates?

У кого-нибудь есть какие-либо предложения по этому поводу?

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

Это было полезно?

Решение

Хорошо, учитывая, что на этот вопрос еще не было ответов, я решил попробовать, но я не эксперт по MVVM.

События, кажется, способ пойти с этим. Однако, как вы указали, может быть утечка памяти, если служба переживает ViewModel. Лучший способ справиться с этим - использовать слабый слушатель событий.

Слабые события позволяют подключиться к событию с слабая ссылка, так что если исходный объект является GC'd, то источник не будет поддерживаться обработчиком события.

Другие советы

Используйте Prism ( http://www.codeplex.com/CompositeWPF ) EventAggregator , который использует шаблон издатель-подписчик, обеспечивая потерю связи между целевым и исходным элементами. Идеально подходит для сценария, который вы описываете.

Я использовал Шаблон наблюдателя (он же шаблон публикации / подписки), чтобы решить эту проблему. проблема. Я сделал класс, который я назвал EventAggregator, который имел все общие методы и члены данных. Я мог бы зарегистрироваться на событие в WidgetListViewModel и опубликовать " Widget Created " событие в CreateWidgetViewModel. Вы можете либо иметь WidgetListViewModel для реализации IDisposable (лучше), чтобы отменить регистрацию вашего события, либо вы можете просто отменить его регистрацию в методе Finalize. Это сработало довольно хорошо, и самое приятное то, что двум моделям представлений не нужно было иметь представление друг о друге.

Для чего-то более сложного или если вам нужно поддерживать различия версий между службой и вашим приложением, вы можете реализовать ModelView, который бы обрабатывал подобные вещи, создавая шаблон ваших приложений M-MV-VM-V. Это может показаться немного излишним, но это может значительно облегчить обслуживание определенных классов проблем. Я знаю, что у меня было несколько проектов, в которые я хотел бы вставить MV, потому что перекрестные помехи между виртуальными машинами и кодом отмены стали просто нелепыми.

Есть несколько вариантов:

<Ол>
  • Используйте ObservableCollection - возможно, это самый простой вариант, но у вас должен быть какой-то вид " master " коллекции в модели, и пользовательский интерфейс должен быть привязан к этой коллекции напрямую, это может быть не "чисто" Архитектура MVVM, но это, вероятно, самый простой способ выполнить работу.

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

  • Используйте некоторых посредников для автоматической очистки событий (как и предлагали другие), но не пишите свои собственные, в этом есть много подводных камней, в WPF есть встроенный класс, который делает это, но я забыл имя (если кто-то помнит имя, пожалуйста, оставьте комментарий).

  • Выполняйте периодические обновления, если ваш класс ViewModel обновляет список каждые X секунд, это единственный способ получать обновления без какого-либо механизма уведомлений, которым вы должны управлять.

  • Я согласен с Кэмероном использовать шаблон WeakEvent.Я создал базовый класс для ViewModel (в моем примере я использую имя PresentationModel), который поддерживает шаблон WeakEvent.

    Возможно, вам пригодится мой пример проекта: http://www.codeplex.com/CompositeExtensions

    jbe

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top