Pregunta

He estado buscando en las muestras de PRISM 2 ideas sobre cómo abordar mejor una nueva aplicación en la que estoy trabajando, que será una aplicación PRISM 2 / WPF. Mirando en particular la aplicación de muestra de inyección de vista que se incluye con PRISM, noté que todas las vistas implementan una interfaz que permite al presentador (o ViewModel) interactuar con la vista.

En el pasado, hice esto al revés, inyecté el presentador en la vista para que la vista pueda llamar directamente a métodos en el presentador un poco como esto:

    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 técnica anterior me pareció lo suficientemente razonable, pero mirando las muestras estoy empezando a cuestionar el enfoque. ¿Alguien tiene puntos de vista (sin juego de palabras) sobre la mejor manera de hacerlo?

  • Agregue el presentador a la vista y haga que la vista interactúe con el presentador
  • Agregue la vista al presentador y haga que el presentador interactúe con la vista
  • ¿Algo totalmente diferente que no haya pensado todavía?
¿Fue útil?

Solución

Creo que todo es cuestión de gustos. Personalmente, disfruto la forma en que lo ves en las muestras que estás viendo. IView tiene un método, ese es SetViewModel (...). IViewModel tiene una propiedad llamada Vista de tipo Objeto, que esencialmente devuelve la IView instanciada DI.

La razón por la que me gusta de esta manera es que casi siempre quiero crear un ViewModel primero y quiero que nobody en el código pueda hacer algo con mi IView, excepto obtener referencia a la instancia ( para ver la inyección o vincular la vista para decir un ContentControl), razón por la cual es de tipo objeto. Si algún código necesita hablar con la Vista, para mí, siempre es a través de la VM ... e incluso entonces la vista se actualiza generalmente a través del enlace. Sería extraño pasar de la vista View- > ViewModel- > UpdateBinding- > a lo que es, VM- > UpdateBinding- > View

Para responder la pregunta, generalmente no necesito una referencia al presentador en el código detrás. Por lo general, puedo manejar eso con comandos de la vista que están vinculados a la VM. En algunos casos, es posible que desee mantener una referencia al presentador para hacer lo que tiene en su ejemplo, pero es evitable dado el conjunto de herramientas correcto (hace que SL sea más difícil que no tenga comandos incorporados).

Como dije, todo es cuestión de gustos ...

-Jer

Otros consejos

El enfoque más común para asignar un ViewModel a una Vista en MVVM es usar una DataTemplate :

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

Cuando muestra una instancia de ViewModel en un ContentControl o ItemsControl, WPF creará automáticamente una vista apropiada para ViewModel y establecerá el DataContext de la vista en la instancia de ViewModel.

De esa manera, no tiene ninguna referencia a la Vista en ViewModel, y la Vista solo hace referencia a ViewModel a través de la propiedad DataContext . En caso de que realmente necesite acceder al ViewModel en el código subyacente de la Vista, siempre puede emitir el DataContext (pero esto implica que la Vista conoce el tipo real del ViewModel, lo que induce el acoplamiento)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top