i can't figure out. try describe problem best can.
i building application using mvvm pattern. have user control aaaview
viewmodel aaaviewmodel
used fill data class cdataclass
. have main window mainview
, viewmodel mainviewmodel
. next have window dialogview
dialogviewmodel
.
so mainviewmodel
(that has own user control) creates dialogviewmodel
(with instance of user control). how can transfer data in cdataclass
between these 2 user controls? tried create property in aaaviewmodel
hold instance of mainviewmodel
or dialogviewmodel
can pass data stuck because couldn't make dependency property.
my goal make user control can used in different views can have different data in underlaying cdataclass
.
just clarify... using user control <views:generalinfoview grid.row="0" />
, don't know how share data between 2 different instances of same user control in different views. point pattern or method appreciate.
thank help.
i don't think it's ideal you've got application architecture diagrammed relationships among views; think better way think set of relationships among viewmodels, views hanging off tree needed. when think way, "how data passed" gets lot simpler. view conduit between viewmodel , user. don't design house set of windows , telephones , try figure out floor plan that. start house , how people live in it.
so easy:
some viewmodels have aaviewmodel
property. there may kinds of simple or complicated views on viewmodels; if view wants let user edit viewmodel's aaviewmodel
stuff, includes aaview
bound appropriately viewmodel's aaviewmodel
. mainviewmodel
, dialogviewmodel
both big complicated interactive views want let edit vm's aaviewmodel
stuff.
if mainviewmodel
dialogviewmodel
's parent, or created temporary instance of dialogviewmodel
put in modal dialog, mainviewmodel
show dialog, , have @ dialogvm.aavm.cdata.isdirty
decide it. or maybe gives dialogvm.aavm
new cdataclass
instance before showing dialog (maybe clone of own instance), , if showmodel()
returns true
, dialogvm.aavm.cdata
.
the point once viewmodels driving everything, becomes relatively simple them communicate each other. parent-child easy: parent gives stuff child , looks @ child brings back. viewmodel can subscribe viewmodel's propertychanged
event; parent viewmodel can monitor children; when happens on child, parent can decide whether update sibling. in general, children should not know @ parents; makes easier reuse child viewmodels in disparate contexts. it's parents decide information.
all aaviewmodel knows handed him copy of cdataclass
; updates public properties accordingly. else (probably aaview
, doesn't know) hands him changes setting properties; updates cdataclass
instance accordingly. after while, unknown him, 1 viewmodel or comes , looks @ cdataclass
.
and communication between views , viewmodels happens via bindings.
update
it turns out you're creating viewmodels in views, , result have no idea how parent can them. , know why it's not idea create child view viewmodels way.
here's how child view/viewmodels in viewmodel-centric design described above:
first, rid of whatever you're doing create child viewmodels inside view.
second, create datatemplate
child viewmodel type. should go in resource dictionary merged resources in app.xaml, it's simple won't kill if lazy , paste resources
of 2 different views it's used.
i don't know namespace declarations like. i'm going assume views in called xmlns:view="..."
, , viewmodels in called xmlns:vm="..."
.
<datatemplate datatype="{x:type vm:aaaviewmodel}"> <view:aaaview /> </datatemplate>
now, can assign aaaviewmodel
contentproperty
of control inherits contentcontrol
(and that's of them), , template instantiated. means xaml create aaaview
, assign instance of aaaviewmodel
datacontext
property of aaaview
created.
so let's create child aaaviewmodel
next, , we'll show in ui.
public class dialogviewmodel { // can create in dialogviewmodel's constructor if need // give parameters won't known until then. private aaaviewmodel _aaavm = new aaaviewmodel(); public aaaviewmodel aaavm { { return _aaavm; } protected set { _aaavm = value; onpropertychanged(nameof(aaavm)); } }
and can display aaavm
in dialogview
:
<grid> <grid.rowdefinitions> <rowdefinition height="auto" /> <rowdefinition height="*" /> </grid.rowdefinitions> <contentcontrol content="{binding aaavm}" grid.row="0" /> <stackpanel orientation="vertical" grid.row="1"> <!-- other stuff --> </stackpanel> </grid>
now how mainviewmodel
in touch dialogviewmodel
? in case of dialogs, since have finite lifespan, it's not big deal let them create own viewmodels. can either way. lean towards having create own in second example below.
not quite same, close. first, once again, rid of whatever you're doing dialog creates own viewmodel.
mainviewmodel.cs
public cdataclass cdc { /* know drill */ } public void showdialog() { var dvm = new dialogviewmodel(); // maybe isn't want; don't know cdataclass does. // i'm assuming has copy constructor. dvm.aaavm.cdc = new cdataclass(this.cdc); if (dialogview.showdialog(dvm).getvalueordefault()) { cdc = dvm.cdc; } }
note next 1 view codebehind, not viewmodel.
dialogview.xaml.cs
public static bool? showdialog(dialogviewmodel dvm) { var vw = new dialogview() { datacontext = dvm }; return vw.showdialog(); }
now, could let dialog continue creating own viewmodel; in case give public property this:
public dialogviewmodel viewmodel => (dialogviewmodel)datacontext;
and showdialog method this:
dialogview.xaml.cs
public static bool? showdialog(cdataclass cdc) { var dlg = new dialogview(); dlg.viewmodel.aaavvm.cdc = cdc; return dlg.showdialog(); }
and parent interact instead:
mainviewmodel.cs
public void showdialog() { var cdcclone = new cdataclass(this.cdc); if (dialogview.showdialog(cdcclone).getvalueordefault()) { cdc = cdcclone; } }
nice , tidy.
if dialog isn't modal, make dialog viewmodel private member of mainviewmodel
, , have mainviewmodel
subscribe events on dialog viewmodel keep abreast of dialog doing. whenever user updates dialog's copy of cdataclass
, dialog raise dataclassupdated
, , mainviewmodel
have handler event sniffs @ _dialogviewmodel.aaavm.cdc
, , decides it. can example code if necessary.
so can see mean building in terms of parent/child viewmodels, , stuffing them views when , appropriate.
Comments
Post a Comment