Eventos vagamente acoplados no WPF sem usar o prisma
-
03-07-2019 - |
Pergunta
Estou trabalhando em um aplicativo WPF e está usando o padrão Model-View-ViewModel.
O aplicativo consiste em dois módulos no momento:
- Painel esquerdo para navegar uma árvore e selecionar um nó
- Painel principal para mostrar o conteúdo do nó da árvore selecionado.
Quero manter esses dois módulos separados, mas quando seleciono um nó no painel esquerdo, preciso demitir um evento em que o painel principal possa se inscrever. Não quero acoplar a esquerda e o painel principal, por isso não quero compartilhar instâncias das classes ViewModel.
Otimamente, eu adoraria usar o Prism (WPF Composite Application Orientance), mas atualmente estou estendendo um aplicativo existente e não posso introduzir mais dependências. O projeto também está no .NET 3.0 (não 3.5), então eu teria que converter o Prism de volta ao .NET 3.0, como está escrito para .NET 3.5.
No Prism, eu resolveria isso usando a infraestrutura de eventos frouxamente acoplada. Ele permite que você demitir um evento em qualquer classe em qualquer camada e ouça qualquer evento em qualquer classe em qualquer camada. Basicamente, o editor e assinante do evento é dissociado.
Eu uso comandos para alcançar esse acoplamento frouxo entre minha visão e meu viewmodel, mas não tenho certeza de como fazer a comunicação de visão cruzada adequada.
Quaisquer dicas ou sugestões são muito apreciadas.
Estou procurando especificamente um verdade Modelo de pub/sub -eventos de peso leve para .NET 2.0/3.0 (sem material do LINQ) ou outra coisa para implementar a comunicação de visualização cruzada (módulo) sem acoplar os dois módulos.
Atualizar: Acabei resolvendo isso de maneira semelhante ao que Glen sugere. Eu tenho um service de eventos separado (eu chamo isso de comandoproxy) e passo esse para todos os viewmodel através dos construtores do meu localizador de serviço (no momento estou usando um localizador de serviço em vez de um contador de IOC). O CommandProxy expõe um conjunto de multidelegatecommants, que é uma extensão do DelegatCommand em Prism (orientação do WPF composto). Basicamente, permite comandos dissociados da árvore visual e que suporta vários assinantes.
Solução
Você tem um contêiner do COI? Uma abordagem simples é criar um serviço personalizado que dispare o evento. O agregador de eventos é genérico, mas você pode criar um serviço específico que faz o que deseja.
Por exemplo, crie um evento de evento que possui um método ONNODESELECT. Esse método dispara um evento modificado que pendura o serviço. O serviço é registrado em seu contêiner do COI, permitindo que os editores e assinantes o acertem. Dessa forma, se seu MainPanel precisar se inscrever, seu MaiinPanelViewModel será injetado com o evento EventingServiec no construtor. Então ele se inscreverá. Outra abordagem se você estiver usando o WPF é retirar o compositário do código da biblioteca de aplicativos compostos e fazer com que o serviço de eventos exponha um compositário. Em seguida, cada assinante (modelo de exibição) registra seu comando no serviço. Quando o OnNodeSelected é chamado, o executivo do CompositEMmand é invocado, notificando todas as partes interessadas.
Falamos sobre o uso de seu próprio serviço para isso nos documentos para orientação do aplicativo composto em www.microsoft.com/composewpf na seção sobre eventos vagamente acoplados no tópico da comunicação. (http://msdn.microsoft.com/en-us/library/cc707836.aspx). Francis Cheung também tem um post sobre isso.