.net - WPF MVVM Light master-detail in TabControl, pass selected item using messages -
i'm new wpf mvvm (light) , need help.
what have master-detail scenario, tabcontrol in main view, master view (productsview) in first tab , multiple different details views (e.g. detailsview) in following tabs.
depending on item selected (selectedproduct) in productsview, want fetch items in detailsview, not - when user clicks tabitem containing details view.
so fetching detail data database should somehow deferred point when user clicks appropriate detail tab (he may not click @ all).
here's xaml:
<!-- main view --> <usercontrol x:class="myapp.views.mainview"> <tabcontrol> <tabcontrol.items> <tabitem> <views:productsview /> </tabitem> <tabitem> <views:detailsview /> </tabitem> <!-- more tabitems details views --> </tabcontrol.items> </tabcontrol> </usercontrol> <!-- products view --> <usercontrol x:class="myapp.views.productsview"> <grid datacontext="{binding source={staticresource locator}, path=productsvm}"> <datagrid itemssource="{binding products}" selecteditem="{binding selectedproduct}"> <datagridtextcolumn binding="{binding path=model.productid}" header="product id" /> </datagrid> </grid> </usercontrol> <!-- details view --> <usercontrol x:class="myapp.views.detailsview"> <grid datacontext="{binding source={staticresource locator}, path=detailsvm.details}"> <stackpanel> <textbox text="{binding path=model.field1}" /> <textbox text="{binding path=model.field2}" /> </stackpanel> </grid> </usercontrol>
and code:
public class productsviewmodel : viewmodelbase { private observablecollection<product> products; public observablecollection<product> products { { return products; } set { // raisepropertychanged set("products", ref products, value); } } private product selectedproduct; public product selectedproduct { { return selectedproduct; } set { // raisepropertychanged , broadcast message of type propertychangedmessage<product> set("selectedproduct", ref selectedproduct, value, true); } } public productsviewmodel(idataservice dataservice) { this.dataservice = dataservice; products = dataservice.getallproducts(); } } public class detailsviewmodel : viewmodelbase { private details details; public details details { { return details; } set { // raisepropertychanged set("details", ref details, value); } } public detailsviewmodel(idataservice dataservice) { this.dataservice = dataservice; messenger.default.register<propertychangedmessage<product>>(this, m => details = dataservice.getdetails(m.newvalue.model.productid)); } }
now works, after product selection, details fetched in details tabs. i've been thinking, maybe when user clicks tab in mainview, mainviewmodel should send message tab index productviewmodel , productviewmodel should send message passing selectedproduct detailsviewmodel of requested tabitem based on tab index, update it's detail data.
but how send message requested tabitem/detailsview based on tab index, not of them?
and roundtripping sounds way complicated. can give me suggestions? or totally wrong? maybe there another, simpler , more elegant solution this?
typically have viewmodel
track tabs
, selectedtab
well, , load current tab in selectedtab
propertychanged
event
something this:
// not expanding these full properties property change // notifications sake of simplicity here observablecollection<viewmodelbase> tabs; viewmodelbase selectedtab; void myviewmodel_propertychanged(object sender, propertychangedeventargs e) { if (e.propertyname == "selectedtab") { if (selectedtab idetailstab) ((idetailstab)selectedtab).loadproduct(selectedproduct); // or depending on structure: var productstab = tabs[0] productsviewmodel; ((idetailstab)selectedtab).loadproduct(productstab.selectedproduct); } }
and xaml this:
<tabcontrol itemssource="{binding tabs}" selecteditem="{binding selectedtab}"> <tabcontrol.resources> <datatemplate datatype="{x:type local:productsviewmodel}"> <local:productsview /> </datatemplate> <datatemplate datatype="{x:type local:detailsviewmodel}"> <local:detailsview /> </datatemplate> </tabcontrol.resources> </tabcontrol>
Comments
Post a Comment