c# - How to cache dynamically switched views by ViewModel-First approach using DataTemplates -
(i using galasoft.mvvmlight framework)
i have views in mainwindow.xaml switching between them dynamically in run-time, user selection.
these views using following technique bind corresponding view-model:
mainwindow.xaml
... <window.resources> <datatemplate datatype="{x:type vm:control1viewmodel}"> <v:control1/> </datatemplate> ... // assume there more 1 datatemplate. every view has unique view-model. </window.resources> ... control1viewmodel.cs
public class control1viewmodel : viewmodelbase { ... } the mainwindow.xaml using following technique switch between above views:
mainwindow.xaml
... <contentcontrol content="{binding currentview}"/> // view appears. ... mainviewmodel.cs
public class mainviewmodel : viewmodelbase { ... private viewmodelbase _currentview; public viewmodelbase currentview { { return _currentview; } private set { _currentview = value; base.raisepropertychanged("currentview"); } } ... } for convenience, didn't add more controls, put 1 (control1) shorten question code section. mentioned above, assume there more 1 view switch.
everytime currentview property set new viewmodelbase value (e.g. control1viewmodel), wpf construct new instance of binded view datatemplate visual tree object, old 1 lost.
that means cannot cache views (e.g. control1) while switching between them.
the solution had found answer "hardcode" view viewmodel (using datacontext), following solution bellow happens:
- i breaking viewmodel-first approach.
- in order not break complete mvvm, have change
currentviewsignature , move code behind ofmainwindow.xaml. - instead of switching
viewmodelbasetypes, switching concrete controls.
i know if there solution without "hardcoding" view view-model, can keep current viewmodelbase switch , viewmodel-first approach.
you can have following approach:
- instead of taking
contentcontroltakeitemscontrol
<itemscontrol itemssource="{binding views}" selecteditem="{binding currentview}"/>
take
itemspanelofitemscontrolgrid ,selecteditemsetz-index1 , rest of items setz-index0. in way 1 view visible @ time on other views.take 2 properties in
mainviewmodel.viewsof typeobservablecollection<viewmodelbase>,currentviewof typeviewmodelbase, binditemscontrols'sitemssource,selecteditemrespectively.
now when want open view, create viewmodel, add views list , set currentview. if there in list, set ascurrentview.
also provide close button if want closed forever. i.e. if close it, removed list , won't cached.
this work if have different views opened in window , can switch between them. , if want can close view.
edit: see below code:
<itemscontrol itemssource="{binding views}"> <itemscontrol.itemspanel> <itemspaneltemplate> <grid margin="10,10,0,10"> </grid> </itemspaneltemplate> </itemscontrol.itemspanel> <itemscontrol.itemcontainerstyle> <style> <setter property="grid.opacity" value="{binding zindex}"/> <setter property="grid.zindex" value="{binding zindex}"/> </style> </itemscontrol.itemcontainerstyle> <itemscontrol.itemtemplate> <datatemplate> <contentcontrol content="{binding}"/> </datatemplate> </itemscontrol.itemtemplate> </itemscontrol> here can see in viewmodel have have property zindex, used show current view on top. whenever want show view, set zindex property of viewmodel 1 , reset reset view 0.
Comments
Post a Comment