Best practice MVVM navigation using Master Detail page? -


i want follow mvvm pattern as possible, don't know if doing navigation quite well. note using masterdetail page , want maintain master page, changing detail side when navigate.

here way navigate viewmodel. in example, viewmodelone viewmodeltwo:

public class viewmodelone : viewmodelbase {     private void gotoviewtwo()     {         var viewtwo = new viewtwo(new viewmodeltwo());         ((masterview)application.current.mainpage).navigatetopage(viewtwo);     } } 

masterview implementation:

public class masterview : masterdetailpage {     public void navigatetopage(page page)     {         detail = new navigationpage(page);         ispresented = false;     } } 

viewtwo implementation:

public partial class viewtwo : pagebase {     public menuview(viewmodeltwo vm)         : base(vm)     {         initializecomponent();     } } 

pagebase implementation:

public class pagebase : contentpage {     public pagebase(viewmodelbase vmb)     {         this.bindingcontext = vmb;     } } 

is best approach (and best performance) navigation? when navigations, app starts run slower , maybe there not doing fine.

is best approach navigation showing masterdetail page?

thanks.

i think you're on right track, there few issues here:

firstly, should not instantiating views in view model. view model becomes aware of view, you've pretty broken pattern.

var viewtwo = new viewtwo(new viewmodeltwo()); 

your view creation should responsibility of master view. in fact, don't need worry creating views, can use datatemplate that. i'll explain later.

firstly, need separate view models views, here propose:

you'll need kind of base class or interface view models in order keep things generic, you'll see why in moment. let's start out simple example:

public abstract class viewmodel : inotifypropertychanged {     public event eventhandler onclosed;             public event eventhandler onopened;      //don't forget implement inotifypropertychanged.     public bool isdisplayed { get; private set; }       public void open()     {         isdisplayed = true;          //todo: raise onopened event (might better idea put in isdisplayed getter.     }      public void close()     {         isdisplayed = false;          //todo: raise onclosed event.     } } 

this of course simple base view model, can extend on later, main reason allow create master view model responsible displaying current page. here's simple example of master view model:

public class masterviewmodel : inotifypropertychanged {     //don't forget implement inotifypropertychanged.     public viewmodel currentpage { get; private set; }      public masterviewmodel()     {         //this example of how set current page.         //you might want use command instead.         currentpage = new movieviewmodel();     }      //todo: other master view model functionality, exiting application. } 

please note inotifypropertychanged better in kind of base class, instead of having re-implement same code on , over.

now masterviewmodel pretty simple, holds current page, purpose of having master allow application level code executed, closing app, way you're keeping logic away other view models.

right, onto stuff.

your detail has relationship it's parent, therefore make sense responsibility of parent manage it. in case, master-detail view model this:

public class movieviewmodel : viewmodel {     protected pickgenreviewmodel childviewmodel { get; private set; }      public movieviewmodel()     {         childviewmodel = new pickgenreviewmodel();          //todo: perhaps subscribe closed event?     }      //just example important thing note     //this method protected because it's movieviewmodel's     //responsibility manage it's child view model.     protected void pickagenre()     {           childviewmodel.open();     }      //todo: other view model functionality. } 

so, we've got kind of view model structure here, bet you're asking "what views?", well, that's datatemplate comes in.

in wpf, it's possible assign view type, example, can assign movieview movieviewmodel in xaml, this:

xmlns:views="clr-namespace:yournamespace.views" xmlns:viewmodels="clr-namespace:yournamespace.viewmodels"  ...   <datatemplate datatype="{x:type viewmodels:movieviewmodel}">     <views:movieview/> </datatemplate> 

ok great!, master view display current page's view, need create contentpresenter, , bind it's content currentpage. master view this:

<window      ...     xmlns:viewmodels="clr-namespace:yournamespace.viewmodels"> <window.datacontext>     <viewmodels:masterviewmodel/> </window.datacontext> <grid>     <contentpresenter content="{binding currentpage}"/> </grid> 

to extend further, it's not masterview needs contain contentpresenter it's child, movieview needs 1 it's child pickgenreviewmodel. can use same method again:

<grid>     <!-- main view code movie view -->     ...     <border visibility="{binding childviewmodel.isdisplayed, converter=...">         <contentpresenter content="{binding childviewmodel}"/>     </border> </grid> 

note: use boolean visibility converter determine whether display child content.

using method don't have worry instantiating views, datatemplate , contentpresenter handles you, need worry mapping view models appropriate view.

phew! lot take in.

the main points take away are:

  1. you shouldn't creating views in view models, remember, ui ui, data data.
  2. view model responsibilities lie whoever owns them, parent-child relationship, makes sense let parent manage child, opposed view model manager.

a final note there more 1 other ways of achieving this, mentioned, kind of view , view model manager responsible creating/removing views , view models.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -