2009-06-30 10 views
8

Ho giocato con il pattern MVP utilizzando winforms negli ultimi due giorni, c'è solo una cosa che non so come fare. Come si crea una sottomaschera da un'altra vista. Questa sarebbe un'opzione valida.Caricamento sottoview di MVP

public class MyForm : IMainFormView 
    { 
     private MainFormPresenter pres; 
     public MyForm() { pres = new MainFormPresenter(this); } 

     //Event from interface. 
     public event EventHandler<EventArgs> LoadSecondForm; 

     public void SomeButtonClick() 
     { 
      LoadSecondForm(this, EventArgs.Empty); 
     } 
    } 

    public class MainFormPresenter 
    { 
     private IMainFormView mView; 

     public MainFormPresenter(IMainFormView view) { 
      this.mView = view; 
      this.Initialize(); 
     } 

     private void Initialize() { 
      this.mView.LoadSecondForm += new EventHandler<EventArgs>(mView_LoadSecondForm); 
     } 


     private void mView_LoadSecondForm(object sender, EventArgs e) { 
      SecondForm newform = new SecondForm(); //Second form has its own Presenter. 
      newform.Load(); // Load the form and raise the events on its presenter. 
     } 
    } 

Sono principalmente interessato a come si potrebbe caricare una sottomaschera utilizzando questo schema, e come si dovrebbe passare dire un ID dalla prima pagina per la sottomaschera.

Grazie.

risposta

2

Dai uno sguardo allo this other SO question. Mentre si riferisce a WPF e non a WinForms, il problema sembra essere lo stesso.

In sostanza, considero la necessità di mostrare una finestra sussidiaria un servizio (si potrebbe chiamarlo WindowsService o DialogService o qualcosa del genere). Questo ti aiuta a mettere le cose in prospettiva, perché non appena te ne rendi conto, l'iniezione di dipendenza diventa la risposta.

Nella tua risposta, lo modellare con gli eventi, ma preferisco un modello più esplicito in cui invochi il metodo ShowDialog di DialogService. Tuttavia, i meccanismi di ciascun approccio non sono così diversi.

1

Un paio di commenti su questo

First Questa

private void mView_LoadSecondForm(object sender, EventArgs e) { 
     SecondForm newform = new SecondForm(); //Second form has its own Presenter. 
     newform.Load(); // Load the form and raise the events on its presenter. 
    } 

Che cosa succede se si decide di sostituire ThirdForm per SecondForm? Devi trovare ogni chiamata di newform = new SecondForm e apportare la modifica.

Invece si dovrebbe avvolgere la creazione del SecondForm in un oggetto Command

public class CreateSecondForm : ICommand 
    { 

     public void Execute() { 
      SecondForm newform = new SecondForm(); //Second form has its own Presenter. 
      newform.Load(); // Load the form and raise the events on its presenter. 
     } 

    } 

Poi qui e qualsiasi altro luogo porta in primo piano seconda forma utilizza questa sintassi

private void mView_LoadSecondForm(object sender, EventArgs e) { 
    CreateSecondForm createCmd = new CreateSecondForm(); 
    createCmd.Execute(); // Load the form and raise the events on its presenter. 
} 

Se si vuole subsitute un forma completamente nuova per SecondForm quindi hai solo un posto dove devi andare. Se si desidera passare lo stato o i valori di configurazione, utilizzare la funzione di costruzione del comando. Puoi persino passare in un altro Presenter o View e avere il comando per estrarre le informazioni dalla sua interfaccia.

Un'altra cosa che consiglio è di registrare i moduli che implementano le visualizzazioni anziché utilizzare il nuovo comando. Questo viene fatto durante l'inizializzazione e il registro si blocca dalla classe principale dell'applicazione.

Ad esempio.

public class MySecondForm : ISecondFormView, IViewForm 
    { 
     //Stuff .... 
     Public ViewFormEnum ViewFormType { 
      return ViewFormEnum.SecondForm; 
     } 
     //Stuff .... 
    } 

in altre parti del software

public void InitializeApp() { 
     //Stuff .... 
     MyApp.ViewForm.Add(new MySecondForm); 

     //Stuff .... 

} 

poi il comando è configurato in questo modo.

Pardon my C# non è la mia lingua principale. Il vantaggio di questo approccio è che l'assembly contenente i moduli può essere scambiato per un assembly diverso con un diverso set di moduli. Ciò è particolarmente utile per automatizzare i test in cui è possibile creare classi di simulazione al posto del modulo. Puoi anche configurarlo per gestire le viste null, utile per pubblicare un sottoinsieme della tua applicazione completa.

Mentre si consiglia vivamente di utilizzare il comando per eseguire il wrapping della creazione delle viste. Il secondo suggerimento di registrare View potrebbe essere eccessivo a seconda dell'applicazione. Nella mia applicazione CAD/CAM ho dozzine di finestre di dialogo e diverse forme principali utilizzate per diversi aspetti di impostazione e controllo di un tavolo da taglio 2D. Tuttavia, in alcune delle altre applicazioni della mia azienda uso un approccio semplice in quanto sono per lo più semplici utilità.