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

Upgrade php version of xampp not success -

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -