Uno può utilizzare MVP ( Model View Presenter ) qui. Questo disaccoppia la vista dalla logica della vista e viene in genere utilizzato per rendere le viste scambiabili, ma non vi è alcun motivo per cui non possa essere utilizzato anche per scambiare l'oggetto Presenter (nel caso sia presente un Presenter per ciascuna modalità). Ciò rende essenzialmente il presentatore un oggetto strategia . Questo sarà simile a questo:
public class MyForm : Form, IView
{
private IPresenter presenter = null;
public MyForm(AppState appState)
{
// For the sake of demonstration, presenters are created here,
// in the real application they could be injected or switched
// at run time:
if (appState == AppState.Annotating)
presenter = new AnnotatingPresenter(this);
else
presenter = new CroppingPresenter(this);
}
}
L'interfaccia IView
deve fornire tutti gli accessi agli elementi / ai controlli del modulo necessari per implementare le loro funzionalità. L'implementazione dell'evento potrebbe essere simile a questa:
private void picBox_MouseDown(object sender, MouseEventArgs e)
{
presenter.OnPicBoxMouseDown(sender,e);
}
Il metodo correlato nel presentatore di annotazioni è simile al seguente:
void OnPicBoxMouseDown(object sender, MouseEventArgs e)
{
if (myview.PicBox.Image == null)
return;
var xDown = e.X;
var yDown = e.Y;
PointF ptImg = new PointF((xDown - absImgPos.X) * scale,
(yDown - absImgPos.Y) * scale);
myView.AnnotateEngine.AddPoint(e.Location, ptImg);
}
Qui, myView
è il riferimento al IView
passato attraverso il costruttore, e AnnotateEngine
e PicBox
sono proprietà che devono essere rese disponibili in IView
e restituiscono i membri annotateEngine
o picBox
rispettivamente.
Ovviamente, ecco alcune decisioni di design che puoi ancora fare in modo diverso. Ad esempio, puoi lasciare il codice comune per entrambi gli stati ancora nella picBox_MouseDow
della vista, o trovare un posto nel livello del presentatore in cui puoi riutilizzarlo da entrambi i Presentatori (potrebbe essere una classe di strumenti o una classe base comune) . Oppure puoi incapsulare l'accesso di tutti i WinForm di IView
in un modo in modo che il livello Presenter non abbia più bisogno di alcun riferimento a WinForms. Dipende dagli obiettivi generali di progettazione, scegli la tua scelta.