Domanda

Ho cercato negli esempi di PRISM 2 idee su come affrontare al meglio una nuova applicazione su cui sto lavorando, che sarà un'app PRISM 2 / WPF. Guardando in particolare l'applicazione di esempio View Injection fornita con PRISM ho notato che tutte le viste implementano un'interfaccia che consente al relatore (o ViewModel) di interagire con la vista.

In passato l'ho fatto al contrario, iniettando il presentatore nella vista in modo che la vista possa chiamare direttamente i metodi sul presentatore un po 'come questo:

    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 tecnica sopra mi è sembrata abbastanza ragionevole, ma guardando i campioni sto iniziando a mettere in discussione l'approccio. Qualcuno ha punti di vista (nessun gioco di parole previsto) sul modo migliore per farlo?

  • Aggiungi il relatore alla vista e ottieni la vista per interagire con il relatore
  • Aggiungi la vista al relatore e fai interagire il relatore con la vista
  • Qualcosa di totalmente diverso a cui non ho ancora pensato?
È stato utile?

Soluzione

Penso che sia tutta una questione di gusti. Personalmente, mi piace il modo in cui lo vedi nei campioni che stai guardando. IView ha un metodo, ovvero SetViewModel (...). IViewModel ha una proprietà chiamata View of type Object, che essenzialmente restituisce IView istanziato DI.

Il motivo per cui mi piace in questo modo è che quasi sempre voglio creare prima un ViewModel e voglio nessuno nel codice per poter fare qualsiasi cosa con il mio IView, tranne che per fare riferimento all'istanza ( per visualizzare l'iniezione o associare la vista a dire ContentControl), motivo per cui è di tipo oggetto. Se un codice deve parlare con la vista, per me è sempre tramite la VM ... e anche allora la vista viene aggiornata di solito tramite associazione. Sarebbe strano passare da View- > ViewModel- > UpdateBinding- > View, rispetto a VM- > UpdateBinding- > View

Per rispondere alla domanda, generalmente non ho bisogno di un riferimento al presentatore nel codebehind. Di solito posso gestirlo con i comandi della vista associati alla VM. In alcuni casi, potresti voler fare riferimento al presentatore per fare ciò che hai nel tuo esempio, ma è evitabile dato il set di strumenti corretto (rende più difficile SL che non abbia comandi incorporati).

Come ho detto, è tutta una questione di gusti ...

-Jer

Altri suggerimenti

L'approccio più comune per mappare un ViewModel a una vista in MVVM è utilizzare un DataTemplate :

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

Quando si visualizza un'istanza ViewModel in ContentControl o ItemsControl, WPF crea automaticamente un'istanza della vista appropriata per ViewModel e imposta il DataContext della vista sull'istanza ViewModel.

In questo modo, non hai alcun riferimento a View in ViewModel e View fa riferimento solo a ViewModel tramite la proprietà DataContext . Nel caso in cui tu abbia davvero bisogno di accedere al ViewModel nel code-behind della View, puoi sempre trasmettere il DataContext (ma questo implica che la View sia a conoscenza del tipo effettivo del ViewModel, che induce l'accoppiamento)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top