Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>EDIT - New (more complete) Answer Below: </p> <p>Ok, C.M is doing a lot of stuff for you, it's all about getting your classes and xaml prepared for C.M to be able to find it. As said above, I prefer to be write code explicit, rather than rely in implicit code assumptions by the framework.</p> <p>So, the Bootstrapper, from the default C.M project is just fine.</p> <pre><code>public class AppBootstrapper : Bootstrapper&lt;MainViewModel&gt; { // ... You shouldn't need to change much, if anything } </code></pre> <p>The section `Bootstrapper' is very important, is it indicates which ViewModel is your first, or main screen, when the app starts up.</p> <pre><code>[Export(Typeof(MainViewModel))] public class MainViewModel : Screen, IShell { [ImportingConstructor] public MainViewModel(YourFirstViewModel firstViewModel, YourSecondViewModel secondviewModel) // etc, for each child ViewModel { } } </code></pre> <p>In the <code>[ImportingConstructor]</code> you don't need to do anything other than specify that the MainViewModel requires the presence of the other ViewModels. In my particular case, I like my MainViewModel to be a container, and container only, the event logic is handled elsewhere. But you could just as easily have your Handle logic here - but that's a while other discussion.</p> <p>Now each child View Model also needs to export themselves so C.M knows where to find them.</p> <pre><code>[Export(Typeof(YourFirstViewModel))] public class YourFirstViewModel : IShell { // VM properties and events here } </code></pre> <p>No need to specify an Importing Constructor if you are just using a default constructor.</p> <p>Now, each of your Views for these will look something like:</p> <pre><code>&lt;UserControl x:Class="Your.Namespace.MainView" xmlns:views="clr-namespace:Your.Namespace.Views" xmlns:cal="http://www.caliburnproject.org" cal:Bind.Model="Your.Namespace.ViewModels.MainViewModel" MinWidth="800" MinHeight="600"&gt; &lt;StackPanel x:Name="RootVisual"&gt; &lt;views:YourFirstView /&gt; &lt;views:YourSecondView /&gt; &lt;!-- other controls as needed --&gt; &lt;/StackPanel&gt; &lt;/UserControl&gt; </code></pre> <p>XAMl or one of the child-views</p> <pre><code>&lt;UserControl x:Class="Your.Namespace.Views.YourFirstView" xmlns:cal="http://www.caliburnproject.org" cal:Bind.Model="Your.Namespace.ViewModels.YourFirstViewModel" MinWidth="800" MinHeight="600"&gt; &lt;Grid x:Name="RootVisual"&gt; &lt;!-- A bunch of controls here --&gt; &lt;/Grid&gt; &lt;/UserControl&gt; </code></pre> <p>What the heck is actually going on here?</p> <p>Well, C.M sees in the bootstrapper, that MainViewModel is the starting point because of the line specifying <code>public class AppBootstrapper : Bootstrapper&lt;MainViewModel&gt;</code>. <code>MainViewModel</code> requires that a <code>YourFirstViewModel</code> and <code>YourSecondViewModel</code> (and other ViewModels) are required in it's constructor, so C.M constructs each one. All of these ViewModels end up in the IoC (making your life much easier later - again, a whole other discussion).</p> <p>C.M handles assigning the datacontext, on your behalf, to each of the views because you specify which VM to bind to with the line like <code>cal:Bind.Model="Your.Namespace.ViewModels.YourFirstViewModel"</code></p> <p>With any luck, that should get you started. Also refer to the C.M example project <code>Caliburn.Micro.HelloEventAggregator</code> as it does exactly what you are looking for (Although, it's described as an Event Aggregator demo, which is also very useful - but again, another discussion)</p> <p>(Original Answer for reverence, below)</p> <p>You need to do this:</p> <pre><code>&lt;UserControl x:Class="Your.Namespace.Here.YourView" xmlns:cal="http://www.caliburnproject.org" cal:Bind.Model="Your.Namespace.Here.YourViewModel" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="1024"&gt; &lt;YourControlLayout /&gt; &lt;/UserControl&gt; </code></pre> <p>Notice the line <code>cal:Bind.Model="Your.Namespace.Here.YourViewModel"</code> which specifies the exact View Model to bind this View to.</p> <p>Don't forget to export your class type, or c.m can't find it.</p> <pre><code>[Export(typeof(YourViewModel))] public class YourViewModel : IShell { ... } </code></pre> <p>Then you can nest your User Controls as you see fit. It's a very good way to make use of C.M, and you will find it highly scalable. The only weakness is that the View and ViewModel must be in the same project (as far as I can tell). But the strength of this approach is you can separate the View and View Model classes into different Namespaces (within the same project) if you wish, to keep things organized.</p> <p>As a commentary on c.m I prefer this method, actually, even if I don't have to nest View UserControls and such. I would rather explicitly declare witch VM a View is bound to (and still let C.M handle all the heavy lifting in IoC) than let c.m "figure it out" from implied code.</p> <p>Even with a good framework: explicit code is more maintainable than implied code. Specifying the bound View Model has the benefit of clearly stating what your data context is expected to be, so you won't need to guess later.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload