Question

J'ai parcouru les exemples de PRISM 2 pour trouver des idées sur la meilleure approche d'une nouvelle application sur laquelle je travaille, qui sera une application PRISM 2 / WPF. En regardant en particulier l'exemple d'application View Injection fourni avec PRISM, j'ai remarqué que toutes les vues implémentaient une interface permettant au présentateur (ou à ViewModel) d'interagir avec cette vue.

Auparavant, je faisais l'inverse, j'injecte le présentateur dans la vue afin que celle-ci appelle directement des méthodes du présentateur un peu comme ceci:

    public partial class SomeView : ModuleBase
    {

        private ISomePresenter _somePresenter;

        public SomeView (ISomePresenter somePresenter):this()
        {
            // Give the view a reference to the presenter
            _somePresenter = somePresenter;
            // Bind the View to the presenter
            DataContext = _somePresenter;
        }

    private void btnSubmit_Click(object sender, RoutedEventArgs e)
    {
        // The view can call actions directly on the presenter (OK I should probably use a command for this)
        _somePresenter.SomeAction();
    }
}

La technique ci-dessus me semblait assez raisonnable, mais en regardant les échantillons, je commence à remettre en question l'approche. Quelqu'un a-t-il un avis (sans jeu de mots) sur la meilleure façon de s'y prendre?

  • Ajoutez le présentateur à la vue et faites en sorte qu'il interagisse avec le présentateur
  • Ajoutez la vue au présentateur et demandez-lui d'interagir avec la vue
  • Quelque chose de totalement différent auquel je n'ai pas encore pensé?
Était-ce utile?

La solution

Je pense que tout est une question de goût. Personnellement, j'apprécie la façon dont vous voyez les exemples que vous regardez. IView a une méthode, SetViewModel (...). IViewModel a une propriété appelée View de type Object, qui renvoie essentiellement l'IView instancié DI.

Si j’aime bien cette façon, c’est que je veux presque toujours créer un ViewModel d’abord et que je ne veux personne dans le code pour pouvoir faire quoi que ce soit avec mon IView, à moins d’obtenir une référence à l’instance ( pour l'injection de vue ou lier la vue à un ContentControl), c'est pourquoi son objet est de type. Si un code doit parler à la vue, pour moi, c'est toujours via la machine virtuelle ... et même dans ce cas, la vue est mise à jour généralement via une liaison. Il serait étrange de passer de View- > ViewModel- > UpdateBinding- > View à ce qu'il est, VM- > UpdateBinding- > View

Pour répondre à la question, je n'ai généralement pas besoin d'une référence au présentateur dans le code ci-dessous. Habituellement, je peux gérer cela avec des commandes de la vue liée à la VM. Dans certains cas, vous voudrez peut-être garder la référence au présentateur pour faire ce que vous avez dans votre exemple, mais cela est évitable si on dispose du bon jeu d’outils (rend SL plus difficile qu’elle n’ait pas de commandes intégrées).

Comme je le disais, tout est une question de goût ...

-Jer

Autres conseils

L’approche la plus courante pour mapper un ViewModel à une vue dans MVVM consiste à utiliser un DataTemplate :

<DataTemplate DataType="{x:Type vm:SomeViewModel}">
    <v:SomeView />
</DataTemplate>

Lorsque vous affichez une instance ViewModel dans un ContentControl ou ItemsControl, WPF instancie automatiquement la vue appropriée pour ViewModel et définit le DataContext de la vue sur l'instance ViewModel.

De cette façon, vous n'avez aucune référence à la vue dans le ViewModel, et la vue ne fait référence qu'au ViewModel via la propriété DataContext . Si vous avez vraiment besoin d'accéder au ViewModel dans le code-behind de la vue, vous pouvez toujours transtyper le DataContext (mais cela implique que la vue connaisse le type réel du ViewModel, ce qui induit un couplage)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top