c# - WPF MVVM changing viewmodel calls dependency property on old viewmodel -



c# - WPF MVVM changing viewmodel calls dependency property on old viewmodel -

i have tabviewmodel wich contains dependency property currentviewmodel. currentviewmodel property bound contentcontrol in view tabview.xaml. tabviewmodel contains command alter currentviewmodel productviewmodel:

public class tabviewmodel: baseviewmodel { public string tabname { get; set; } //public list<baseviewmodel> viewmodels { get; set; } private pageviewmodel _currentviewmodel; public pageviewmodel currentviewmodel { { homecoming _currentviewmodel; } set { _currentviewmodel = value; onpropertychanged("currentviewmodel"); } } public tabviewmodel(string tabname, pageviewmodel currentviewmodel) { tabname = tabname; currentviewmodel = currentviewmodel; } private icommand _navigatetoproductviewmodelcommand; public icommand navigatetoproductviewmodelcommand { { if (_navigatetoproductviewmodelcommand == null) { _navigatetoproductviewmodelcommand = new delegatecommand<product>( (p) => { currentviewmodel = new productviewmodel(); }); } homecoming _navigatetoproductviewmodelcommand; } } }

tabview.xaml

<usercontrol x:class="monitoring_tool.views.tabview" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:ignorable="d" d:designheight="300" d:designwidth="300"> <grid> <grid.rowdefinitions> <rowdefinition height="auto" /> <rowdefinition height="*" /> </grid.rowdefinitions> <progressbar value="{binding path=currentviewmodel.pageprogress}" height="5" grid.row="0" margin="0,0,0,10"> <progressbar.style> <style targettype="{x:type progressbar}"> <setter property="template"> <setter.value> <controltemplate targettype="progressbar"> <border borderthickness="0,0,0,0" background="lightgray" cornerradius="0" padding="0"> <grid x:name="part_track"> <rectangle x:name="part_indicator" horizontalalignment="left" fill="#00b6fa" /> </grid> </border> </controltemplate> </setter.value> </setter> </style> </progressbar.style> </progressbar> <contentcontrol content="{binding path=currentviewmodel}" grid.row="1" /> </grid>

i instantiate tabviewmodel this:

new tabviewmodel("producten", new productsviewmodel())

the productsview.xaml shown should be. in productsview.xaml phone call command tabviewmodel this:

<datagrid.inputbindings> <mousebinding mouseaction="leftdoubleclick" command="{binding datacontext.navigatetoproductviewmodelcommand, relativesource={relativesource ancestortype={x:type views:tabview}}}"/> </datagrid.inputbindings>

when datagrid empty, command executed , productview.xaml appears should be. when datagrid not empty somthing unusual happens:

the command executed, , when debug can see currentviewmodel changed productviewmodel. when onpropertychanged("currentviewmodel") called. there set phone call (value = null) depedency property (selectedassetcategory) on productsviewmodel, wich replaced , doesn't exits anymore?!

when set currentviewmodel = null same thing happens, can currentviewmodel = new productsviewmodel. guess it's somthing updating ui?

in app.xaml defined next recources:

<datatemplate datatype="{x:type viewmodels:tabviewmodel}"> <views:tabview /> </datatemplate> <datatemplate datatype="{x:type viewmodels:productsviewmodel}"> <views:productsview /> </datatemplate> <datatemplate datatype="{x:type viewmodels:productviewmodel}"> <views:productview /> </datatemplate>

the productsviewmodel looks this:

class productsviewmodel: pageviewmodel { private readonly monitotingtoolentities _databaseentities; public productsviewmodel() { _databaseentities = new monitotingtoolentities(); assetcategories = new observablecollection<assetcategory>(_databaseentities.assetcategory.tolist()) { new assetcategory() {assetcategoryid = 0, assetcategoryname = "alles"} }; results = new observablecollection<product>(); } public observablecollection<assetcategory> assetcategories { get; set; } private assetcategory _selectedassetcategory; public assetcategory selectedassetcategory { { homecoming _selectedassetcategory; } set { _selectedassetcategory = value; //this 1 called value = null onpropertychanged("selectedassetcategory"); filter(); } } public observablecollection<product> results { get; set; } public void filter() { results.clear(); list<product> products = selectedassetcategory.assetcategoryid == 0 ? _databaseentities.product.tolist() : selectedassetcategory.product.tolist(); foreach (product product in products) { results.add(product); } } }

productsview.xaml:

<usercontrol x:class="monitoring_tool.views.productsview" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:views="clr-namespace:monitoring_tool.views" xmlns:componentmodel="clr-namespace:system.componentmodel;assembly=windowsbase" xmlns:sys="clr-namespace:system;assembly=mscorlib" xmlns:viewmodels="clr-namespace:monitoring_tool.viewmodels" mc:ignorable="d" d:designheight="300" d:designwidth="300"> <usercontrol.resources> <collectionviewsource x:key="cvsassetcategories" source="{binding path= assetcategories}" > <collectionviewsource.sortdescriptions> <componentmodel:sortdescription propertyname="assetcategoryid"/> </collectionviewsource.sortdescriptions> </collectionviewsource> <collectionviewsource x:key="cvsresults" source="{binding path= results}" > <collectionviewsource.groupdescriptions> <propertygroupdescription propertyname="assetcategory.assetcategoryname" /> </collectionviewsource.groupdescriptions> </collectionviewsource> <style targettype="image" x:key="imagedisabledstyle"> <style.triggers> <trigger property="isenabled" value="false"> <setter property="opacity" value="0.5" /> </trigger> </style.triggers> </style> </usercontrol.resources> <grid> <grid.rowdefinitions> <rowdefinition height="auto" /> <rowdefinition height="*" /> <rowdefinition height="auto" /> </grid.rowdefinitions> <grid margin="0, 0, 0, 10" grid.row="0"> <grid.columndefinitions> <columndefinition width="auto"/> <columndefinition width="2*"/> <columndefinition width="3*"/> <columndefinition width="auto"/> <columndefinition width="*"/> <columndefinition width="*"/> <columndefinition width="auto"/> <columndefinition width="auto"/> </grid.columndefinitions> <textblock text="asset categorie:" grid.column="0" verticalalignment="center" margin="0,0,10,0"/> <combobox grid.column="1" itemssource="{binding source={staticresource cvsassetcategories}}" displaymemberpath="assetcategoryname" selecteditem="{binding selectedassetcategory}" margin="0,0,10,0"/> <textblock text="zoeken:" grid.column="3" verticalalignment="center" margin="0,0,10,0"/> <combobox grid.column="4" selecteditem="{binding selectedsearchfield}" margin="0,0,10,0"/> <textbox text="{binding path=searchquery, mode=twoway, updatesourcetrigger=propertychanged}" grid.column="5" margin="0,0,10,0"> <textbox.inputbindings> <keybinding command="{binding path=searchcommand}" commandparameter="{binding searchquery}" key="enter" /> </textbox.inputbindings> </textbox> <button grid.column="6" command="{binding searchcommand}" commandparameter="{binding searchquery}" padding="5,0,5,0" margin="0,0,10,0" > <button.content> <image source="/recourses/searchicon.png" stretch="none" verticalalignment="top" style="{binding source={staticresource imagedisabledstyle}}"/> </button.content> </button> <button grid.column="7" command="{binding cancelsearchcommand}" isenabled="{binding cancelsearchenabled}" padding="5,0,5,0"> <button.content> <image source="/recourses/cancelsearchicon.png" stretch="none" verticalalignment="top" style="{binding source={staticresource imagedisabledstyle}}"/> </button.content> </button> </grid> <datagrid name="dgproducts" autogeneratecolumns="false" rowheaderwidth="0" margin="0,0,0,10" grid.row="1" isreadonly="true" selectionmode="single" canuserreordercolumns="false" enablerowvirtualization="true" virtualizingpanel.isvirtualizingwhengrouping="true" itemssource="{binding source={staticresource cvsresults}}" selecteditem="{binding selectedproduct}"> <datagrid.cellstyle> <style targettype="datagridcell"> <setter property="borderthickness" value="0"/> </style> </datagrid.cellstyle> <datagrid.inputbindings> <mousebinding mouseaction="leftdoubleclick" command="{binding datacontext.navigatetoproductviewmodelcommand, relativesource={relativesource ancestortype={x:type views:tabview}}}" /> </datagrid.inputbindings> <datagrid.resources> <style targettype="datagridcolumnheader" x:key="dgverticalcolumnheader"> <setter property="layouttransform"> <setter.value> <rotatetransform angle="270" /> </setter.value> </setter> </style> <solidcolorbrush x:key="{x:static systemcolors.highlightbrushkey}" color="lightgray"/> <solidcolorbrush x:key="{x:static systemcolors.highlighttextbrushkey }" color="black"/> </datagrid.resources> <datagrid.groupstyle> <groupstyle> <groupstyle.containerstyle> <style targettype="groupitem"> <setter property="template"> <setter.value> <controltemplate targettype="groupitem"> <stackpanel> <textblock text="{binding path=name}" background="darkgray" padding="2,0,0,0"/> <itemspresenter/> </stackpanel> </controltemplate> </setter.value> </setter> </style> </groupstyle.containerstyle> </groupstyle> </datagrid.groupstyle> <datagrid.columns> <datagridtextcolumn binding="{binding path=manager.managername}" header="manager" /> <datagridtextcolumn binding="{binding path=productname}" header="product" /> <datagridtextcolumn binding="{binding path=monitoringby}" header="monitoring door" /> <datagridtextcolumn binding="{binding path=aumproduct}" header="aum product (mln)" /> <datagridtextcolumn binding="{binding path=aumproductdate, stringformat='{}{0:dd-mm-yyyy}'}" header="datum aum product" /> <datagridtextcolumn binding="{binding path=aumstrategy}" header="aum strategie (mln)" /> <datagridtextcolumn binding="{binding path=aumstrategydate, stringformat='{}{0:dd-mm-yyyy}'}" header="datum aum strategie" /> <datagridtextcolumn binding="{binding path=aum}" header="aum (mln)" /> <datagridtextcolumn binding="{binding path=totalexpenseratio}" header="ter (bp)" /> <datagridtextcolumn binding="{binding path=fee}" header="total fee" /> </datagrid> <grid grid.row="2"> <grid.columndefinitions> <columndefinition width="auto" /> <columndefinition width="*" /> <columndefinition width="auto" /> <columndefinition width="auto" /> </grid.columndefinitions> <textblock text="{binding path=results.count, stringformat='{}{0} producten'}" grid.column="0" margin="0,0,0,0"/> <button grid.column="2" content="toevoegen" padding="5,0,5,0" margin="0,0,10,0" command="{binding addproductcommand}" /> <button grid.column="3" content="verwijderen" padding="5,0,5,0" command="{binding path=removeproductcommand}" commandparameter="{binding path=selectedproduct}"/> </grid> </grid>

pageviewmodel abstract class:

public abstract class pageviewmodel: baseviewmodel { private int _pageprogress; public int pageprogress { { homecoming _pageprogress; } set { _pageprogress = value; onpropertychanged("pageprogress"); } } }

it's kind of weird has collectionviewsource (cvsassetcategories) bound combobox. if bind straight combobox without using collectionviewsource dependency property not called. however, utilize collectionviewsource sortdescriptor. solution not null check on setter dependency property, think nasty way go.

c# wpf xaml mvvm

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -