How to Structure a C# WinForms Model-View-Presenter (Passive View) Program? -


i designing gui has following basic idea (similarly modeled after visual studio's basic look-and-feel):

  1. file navigation
  2. control selector (for selecting display in editor component)
  3. editor
  4. logger (errors, warnings, confirmation, etc.)

for now, using treeview file navigation, listview selecting controls displayed in editor , richtextbox logger. editor have 2 types of editing modes depending on selected in treeview. editor either richtextbox manually editing text inside files, or panel drag/drop datagridviews , sub-textboxes editing in panel.

i attempting follow passive view design pattern complete separation of model view , vice versa. nature of project component add subject edit/removal. such, need there independence given control next. if today using treeview file navigation, tomorrow told use else, want implement new control relative ease.

i not understand how structure program. understand 1 presenter per control, not know how make work such have view (the entire gui of program) controls (sub-views) such entire view replaceable individual controls reflect model.

in main view, supposed lightweight passive view standards, implement sub-views individually? if so, have interface inavigator abstract role of navigator object. navigator need presenter , model act between navigator view , main view. feel getting lost in design pattern jargon somewhere.

the similarly-related question can found here, not answer question in sufficient detail.

will please me understand how "structure" program? appreciate help.

thanks,

daniel

abstraction good, it's important remember @ point something has know thing or 2 thing or two, or else we'll have pile of nicely abstracted legos sitting on floor instead of them being assembled house.

an inversion-of-control/dependency injection/flippy-dippy-upside-down-whatever-we're-calling-it-this-week container autofac can in piecing together.

when throw winforms application, end repeating pattern.

i'll start program.cs file configures autofac container , fetches instance of mainform it, , shows mainform. people call shell or workspace or desktop @ rate it's "the form" has menu bar , displays either child windows or child user controls, , when closes, application exits.

next aforementioned mainform. basic stuff drag-and-dropping splitcontainers , menubars , such in visual studio visual designer, , start getting fancy in code: i'll have key interfaces "injected" mainform's constructor can make use of them, mainform can orchestrate child controls without having know them.

for example, might have ieventbroker interface lets various components publish or subscribe "events" barcodescanned or productsaved. allows parts of application respond events in loosely coupled way, without having rely on wiring traditional .net events. example, editproductpresenter goes along editproductusercontrol this.eventbroker.fire("productsaved", new eventargs<product>(blah)) , ieventbroker check list of subscribers event , call callbacks. example, listproductspresenter listen event , dynamically update listproductsusercontrol attached to. net result if user saves product in 1 user control, user control's presenter can react , update if happens open, without either control having aware of each other's existence, , without mainform having orchestrate event.

if i'm designing mdi application, might have mainform implement iwindowworkspace interface has open() , close() methods. inject interface various presenters allow them open , close additional windows without them being aware of mainform directly. example, listproductspresenter might want open editproductpresenter , corresponding editproductusercontrol when user double-clicks row in data grid in listproductsusercontrol. can reference iwindowworkspace--which mainform, doesn't need know that--and call open(newinstanceofaneditcontrol) , assume control shown in appropriate place of application somehow. (the mainform implementation would, presumably, swap control view on panel somewhere.)

but how hell listproductspresenter create instance of editproductusercontrol? autofac's delegate factories true joy here, since can inject delegate presenter , autofac automagically wire if factory (pseudocode follows):

 public class editproductusercontrol : usercontrol {     public editproductusercontrol(editproductpresenter presenter)     {         // initialize databindings based on properties of presenter     } }  public class editproductpresenter {     // autofac magic when sees injected anywhere     public delegate editproductpresenter factory(int productid);      public editproductpresenter(         isession session, // nhibernate session reference         ieventbroker eventbroker,         int productid)    // optional product identifier     {         // stuff....     }      public void save()     {         // 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 data grid, etc.     } }  

so listproductspresenter knows edit feature set (i.e., edit presenter , edit user control)--and fine, go hand-in-hand--but doesn't need know of dependencies of edit feature set, instead relying on delegate provided autofac resolve of dependencies it.

generally, find have one-to-one correspondence between "presenter/view model/supervising controller" (let's not caught on differences @ end of day quite similar) , "usercontrol/form". usercontrol accepts presenter/view model/controller in constructor , databinds appropriate, deferring presenter as possible. people hide usercontrol presenter via interface, ieditproductview, can useful if view not passive. tend use databinding communication done via inotifypropertychanged , don't bother.

but, make life easier if presenter shamelessly tied view. property in object model not mesh databinding? expose new property does. never going have editproductpresenter , editproductusercontrol 1 layout , want write new version of user control works same presenter. edit them both, intents , purpose 1 unit, 1 feature, presenter existing because unit testable , user control not.

if want feature replaceable, need abstract entire feature such. might have inavigationfeature interface mainform talks to. can have treebasednavigationpresenter implements inavigationfeature , consumed treebasedusercontrol. , might have carouselbasednavigationpresenter implements inavigationfeature , consumed carouselbasedusercontrol. user controls , presenters still go hand-in-hand, mainform not have care if interacting tree-based view or carousel-based one, , swap them out without mainform being wiser.

in closing, easy confuse yourself. pedantic , uses different terminology convey subtle (and oftentimes unimportant) differences between similar architectural patterns. in humble opinion, dependency injection wonders building composable, extensible applications, since coupling kept down; separation of features "presenters/view models/controllers" , "views/user controls/forms" wonders quality since logic pulled former, allowing unit tested; , combining 2 principles seems you're looking for, you're getting confused on terminology.

or, full of it. luck!


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -