Слабосвязанные события в WPF без использования Prism

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

Вопрос

Я работаю над приложением WPF и использую шаблон Model-View-ViewModel.

На данный момент приложение состоит из двух модулей:

  • Левая панель для просмотра дерева и выбора узла
  • Главная панель для отображения содержимого выбранного узла дерева.

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

В идеале я хотел бы использовать Prism (Руководство по составным приложениям WPF), но в настоящее время я расширяю существующее приложение и не могу добавлять дополнительные зависимости.Проект также работает на .NET 3.0 (а не на 3.5), поэтому мне придется конвертировать Prism обратно в .NET 3.0, как это написано для .NET 3.5.

В Prism я бы решил эту проблему, используя слабосвязанную инфраструктуру событий.Это позволяет вам запускать событие в любом классе на любом уровне и прослушивать любое событие в любом классе на любом уровне.По сути, издатель и подписчик события разделены.

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

Любые советы или предложения очень ценятся.

Я специально ищу Действительно легкая модель событий pub/sub для .NET 2.0/3.0 (без LINQ) или что-то еще для реализации перекрестной связи View (модуля) без объединения двух модулей.

Обновлять:В итоге я решил эту проблему аналогично тому, что предлагает Глен.У меня есть отдельный EventService (я называю его CommandProxy), и я передаю его каждой ViewModel через конструкторы в моем локаторе сервисов (на данный момент я использую локатор сервисов вместо IoC-контейнера).CommandProxy предоставляет набор MultiDelegateCommants, который является расширением DelegateCommand в Prism (руководство по составному WPF).По сути, он позволяет использовать команды, отделенные от визуального дерева и поддерживающие несколько подписчиков.

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

Решение

У вас есть контейнер IoC?Один простой подход — создать специальную службу, которая запускает событие.Агрегатор событий является универсальным, но вы можете создать конкретную службу, которая будет делать то, что вы хотите.

Например, создайте EventingService с методом OnNodeSelected.Этот метод запускает событие NodeSelected, которое отключается от службы.Затем служба регистрируется в вашем IoC-контейнере, что позволяет издателям и подписчикам получить к ней доступ.Таким образом, если, скажем, ваша MainPanel должна подписаться, то в вашу MainPanelViewModel будет добавлен EventingServiec в ее конструктор.Затем он подпишется.Другой подход, если вы используете WPF, — извлечь CompositeCommand из кода библиотеки составных приложений и предоставить службе обработки событий CompositeCommand.Затем каждый подписчик (модель представления) регистрирует свою команду в сервисе.При вызове OnNodeSelected вызывается выполнение CompositeCommand, тем самым уведомляя все заинтересованные стороны.

Мы говорим об использовании для этого вашей собственной службы в документации по составному приложению на сайте www.microsoft.com/compositewpf в разделе «Слабосвязанные события» в теме «Связь».(http://msdn.microsoft.com/en-us/library/cc707836.aspx).У Фрэнсиса Чунга также есть пост на эту тему.

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