c# - WPF Mvvm navigation with parameters -


following this tutorial (among others) , reading questions asked here i've constructed navigation mechanism allow me pass parameters between viewmodels:
object base - every view model inherits it:

public abstract class objectbase : inotifypropertychanged {     //inotifypropertychanged members     ...      //navigation handling     public abstract objectbase backlocation { get; }      public abstract event action<objectbase> navigateto;      public abstract string viewheader { get; } } 

mainviewmodel - in charge of navigation:

public class mainviewmodel : objectbase {     private objectbase _selectedview;     private commandbase _backcommand;      public mainviewmodel()     {         selectedview = new firstviewmodel();     }      public objectbase selectedview     {         { return _selectedview; }         set         {             setproperty(ref _selectedview, value);             //register navigation event of new view              selectedview.navigateto += (target)=> { selectedview = target; };         }     }      //this command bound button on main view     public commandbase backcommand     {         { return _backcommand ?? (_backcommand = new commandbase(back)); }     }      private void back(object obj)     {         if (selectedview.backlocation != null)         {             selectedview = selectedview.backlocation;         }         else         {             application.current.shutdown();         }     } } 

and main view:

<window ...     <window.datacontext>     <vm:mainviewmodel/> </window.datacontext> <window.resources>     <datatemplate datatype="{x:type vm:firstviewmodel}">         <views:firstview/>     </datatemplate>     <datatemplate datatype="{x:type vm:secondviewmodel}">         <views:secondview/>     </datatemplate> </window.resources> <contentpresenter content="{binding selectedview}"/> </window> 

my problem is: if set datatemplates in main view above makes each view aware of it's datacontext if want add datacontext explicitly view in order use intellisense this:

<usercontrol x:class="wpf_navigationtest.views.firstview"          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          xmlns:viewmodels="clr-namespace:wpf_navigationtest.viewmodels"> <!--this causes view model's constructor called again--> <usercontrol.datacontext>     <viewmodels:firstviewmodel/> </usercontrol.datacontext> <grid>     <textblock text="user control 1" fontsize="40"/>     </grid> 

the view model's constructor called twice, losing parameters passed navigate event.

the problem here setting datacontext inside usercontrol, , in main view model.

<usercontrol.datacontext>     <viewmodels:firstviewmodel/> </usercontrol.datacontext> 

the code above instantiating new firstviewmodel every time usercontrol created. therefore when control gets created contentcontrol (based on datatemplate), goes ahead , creates new firstviewmodel.

so, solution here remove usercontrol.datacontext declaration in usercontrol, , can instead set datacontext of contentcontrol of selectedview.

<contentpresenter content="{binding selectedview}"                   datacontext="{binding selectedview}"/> 

in order use multiple view models single view, can add datatemplate:

<datatemplate datatype="{x:type vm:thirdviewmodel}">     <views:secondview/> </datatemplate> 

for design-time data (to intellisense), can make use of d:datacontext explained in this article.

this require set view models static resources, recommend creating them in separate resourcedictionary.


Comments

Popular posts from this blog

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -

YouTubePlayerFragment cannot be cast to android.support.v4.app.Fragment -