Слабосвязанные события в WPF без использования Prism - PullRequest
4 голосов
/ 22 октября 2008

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

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

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

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

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

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

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

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

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

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

1 Ответ

7 голосов
/ 22 октября 2008

Есть ли у вас контейнер IoC? Один простой подход заключается в создании пользовательской службы, которая запускает событие. Event Aggregator является универсальным, но вы можете создать конкретный сервис, который делает то, что вы хотите.

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

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

...