How to structure a C # WinForms Model-View-Presenter program (Passive View)?

I am developing a GUI that has the following basic idea (similarly modeled after the main view of Visual Studio):

  • File navigation
  • Control selector (to select the display on the editor component)
  • Editor
  • Logger (errors, warnings, confirmation, etc.)

Currently, I will use TreeView to navigate files, ListView to select the controls to be displayed in the Editor, and RichTextBox for Logger. The editor will have 2 types of editing modes depending on what is selected in the TreeView. The editor will be either a RichTextBox for manual editing of text inside files, or it is a panel with Drag / Drop DataGridViews and subtext blocks for editing on this panel.

I am trying to execute a passive view template to completely separate the model from the view and vice versa. The nature of this project is that any added component can be edited / deleted. Thus, I need independence from this control to the next. If today I use TreeView to navigate files, but tomorrow they tell me to use something else, then I want to easily implement a new control.

I just don’t understand how to structure the program. I understand one Presenter per Control, but I don’t know how to make it work so that I have a View (the entire graphical interface of the program) with controls (sub-Views), so ENTIRE View can be changed, as well as individually reflect my model.

, , - ? , , INavigator Navigator. Navigator . , - .

, .

-, , , "" ? .

,

Daniel

+5
2

, , - - - - , , .

/ /flippy -dippy-upside-down-whatever-we're-call-it-this-week , Autofac .

WinForms, .

Program.cs, Autofac, MainForm MainForm. , "", , , , , .

MainForm. , SplitContainers MenuBar .. Visual Studio, : , "" MainForm, , MainForm , .

, IEventBroker, "", BarcodeScanned ProductSaved. , .NET. , EditProductPresenter, EditProductUserControl, this.eventBroker.Fire("ProductSaved", new EventArgs<Product>(blah)), IEventBroker . , ListProductsPresenter ListProductsUserControl, . , , , , - , , MainForm .

MDI, MainForm IWindowWorkspace, Open() Close(). , , MainForm. , ListProductsPresenter EditProductPresenter EditProductUserControl, ListProductsUserControl. IWindowWorkspace, MainForm, - Open(newInstanceOfAnEditControl) , - . ( MainForm, -, -.)

, , ListProductsPresenter EditProductUserControl? Autofac - , , Autofac , factory ( ):


public class EditProductUserControl : UserControl
{
    public EditProductUserControl(EditProductPresenter presenter)
    {
        // initialize databindings based on properties of the presenter
    }
}

public class EditProductPresenter
{
    // Autofac will do some magic when it sees this injected anywhere
    public delegate EditProductPresenter Factory(int productId);

    public EditProductPresenter(
        ISession session, // The NHibernate session reference
        IEventBroker eventBroker,
        int productId)    // An optional product identifier
    {
        // do stuff....
    }

    public void Save()
    {
        // do stuff...
        this.eventBroker.Publish("ProductSaved", new EventArgs(this.product));
    }
}

public class ListProductsPresenter
{
    private IEventBroker eventBroker;
    private EditProductsPresenter.Factory factory;
    private IWindowWorkspace workspace;

    public ListProductsPresenter(
        IEventBroker eventBroker,
        EditProductsPresenter.Factory factory,
        IWindowWorkspace workspace)
    {
       this.eventBroker = eventBroker;
       this.factory = factory;
       this.workspace = workspace;

       this.eventBroker.Subscribe("ProductSaved", this.WhenProductSaved);
    }

    public void WhenDataGridRowDoubleClicked(int productId)
    {
       var editPresenter = this.factory(productId);
       var editControl = new EditProductUserControl(editPresenter);
       this.workspace.Open(editControl);
    }

    public void WhenProductSaved(object sender, EventArgs e)
    {
       // refresh the data grid, etc.
    }
}

, ListProductsPresenter Edit (.. ) - , - Edit, , Autofac, .

, , "/ / " ( , ) "UserControl/Form". UserControl / / , , . UserControl , IEditProductView, , . , INotifyPropertyChanged .

, . ? , . EditProductPresenter EditProductUserControl , , . , , , , .

, , . , INavigationFeature, MainForm. TreeBasedNavigationPresenter, INavigationFeature TreeBasedUserControl. CarouselBasedNavigationPresenter, INavigationFeature CarouselBasedUserControl. - , MainForm , , MainForm .

, . , ( ) , . , , , ; "/ /" "/ /" , , ; , -, , , .

. !

+22

, 2 , . , DAYS , - , , 10 Google!

, , - ? , , , :

: , ( , ) , (view)

FormMain, 2 :

ControlsView ( 3 ) DocumentView ( )

" " .. . ControlsView " ", TreeView "DocumentView" .

, MVP, , , . , .

, "", ControlsPresenter , , , , , , - , DocumentView (, ).

, ControlsPresenter -, "PageAdded".

ControlsPresenter, DocumentPresenter, "" , ControlsPesenter , , DocumentPresenter , .

:

- "ScanButtonClicked"

Presenter - , Scanner AcquireImages :

GDPictureScanning scanner = new GDPictureScanning();

IEnumerable<Page> pages = scanner.AquireImages();
foreach (Page page in pages)
{
m_DocumentModel.AddPage(page);                
//The view gets notified of new pages via events raised by the model
//The events are subscribed to by the various presenters so they can 
//update views accordingly                
}

, "yield return new Page (PageID)". m_DocumentModel.AddPage(). , . "" .

, , - - Program.cs :

static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

IDocumotiveCaptureView view = new DocumotiveCaptureView();
IDocumentModel model = new DocumentModel();
IDocumotiveCapturePresenter Presenter = new DocumotiveCapturePresenter(view, model);
IControlsPresenter ControlsPresenter = new ControlsPresenter(view.ControlsView, model);
IDocumentPresenter DocumentPresenter = new DocumentPresenter(view.DocumentView, model);

Application.Run((Form)view);                                                         
}

, , !

, - , - , ...

+2

All Articles