c# - WPF Caliburn.Micro - Best way to navigate in Singe Window Application -
- my history:
i'm developing wpf application, run in full screen on touch screen. navigation in application can done clicking button on each page ("back" or "logout").
this not universal app, looks like.
assumptions of project:
- application run on full screen mode in windows 7 on touch screen.
- i'm using caliburn.micro mvvm framework.
problem , question:
i've got 1 window , 3 usercontrol (and viewmodels) concept art
window shellview usercontrol loginview usercontrol ordersview usercontrol orderdetailview when application starting, i'm set loginview default , load using cm conductor activateitem method, don't know how set view usercontrol loginview
i have read: this question doesn't cover case , this answer it's hard understand me.
my ideas:
- make static method in shellviewmodel like:
shellviewmodel
public static void setordersview() { activateitem(new ordersviewmodel()); // error : object reference required non-static field, method, or property 'caliburn.micro.conductorbase<object>.activateitem(object) } shellviewmodel.setordersview(); - make listener in shellviewmodel , send event child viewmodel ( don't know how achieve it)
question: best way handle navigation in case?
- application architecture:
shellview
<window> <contentcontrol x:name="activeitem" /> </window> shellviewmodel
public class shellviewmodel : conductor<object>, ishell { public shellviewmodel() { loaddefault(); } public void loaddefault() { activateitem(new loginviewmodel()); } } loginview
<usercontrol> <button x:name="login" /> </usercontrol> loginviewmodel
public class loginviewmodel : propertychangedbase { public void login() { if (loginmanager.login("user", "password")) { // how redirect user ordersview? } } }
i have similar applications 1 shell window , many activated views inside , dialog windows. should use eventaggregator pattern these needs , caliburn has implementation.
how achieve:
minimum shell signature
public class shellviewmodel : conductor<object>, ihandle<changepagemessage>, ihandle<openwindowmessage> you need 2 fields inside (second 1 dialogs):
public ieventaggregator eventaggregator { get; private set; } public iwindowmanager windowmanager { get; private set; } i've set single instances of objects through ioc. can define them singletons. eventaggregator needs subscription on object ihandles implemented.
eventaggregator.subscribe(this); //you should unsubscribe when message handling no longer needed handlers implementation:
public void handle(changepagemessage message) { var instance = ioc.getinstance(message.viewmodeltype, null);//or create viewmodel type activateitem(instance); } public void handle(openwindowmessage message) { var instance = ioc.getinstance(message.viewmodeltype, null);//or create viewmodel type windowmanager.showwindow(instance); } messages event aggregator can marker classes useful pass more parameters ours openwindowmessage , changepagemessage classes - absolutely similar content, example:
public class openwindowmessage { public readonly type viewmodeltype; public openwindowmessage(type viewmodeltype) { viewmodeltype = viewmodeltype; } } all viewmodels can subscribe eventaggregator instance , handle messages communication, or initial parameters. have myviewmodelinitmessage classes every viewmodel, , use 2 publish methods together.
eventaggregator.publish(new changepagemessage(typeof(myviewmodel))); eventaggregator.publish(new myviewmodelinitmessage("...all needed parameters")); so when publish 2 - mine viewmodel activated, subscribes eventaggregator(don't forget or second message handling never occurs), , handle initmessage right after.
now eventaggregator can send messages between viewmodels subscribed it.
that seems pretty common solution.
Comments
Post a Comment