РЕДАКТИРОВАТЬ - Новый (более полный) ответ ниже:
Хорошо, CM делает много вещей для вас, это все о том, как подготовить ваши классы и xaml к CM, чтобы иметь возможность найти его.Как уже было сказано выше, я предпочитаю писать код явно, а не полагаться на предположения о неявном коде, создаваемые платформой.
Итак, Bootstrapper из проекта CM по умолчанию просто в порядке.
public class AppBootstrapper : Bootstrapper<MainViewModel>
{
// ... You shouldn't need to change much, if anything
}
Раздел `Bootstrapper 'очень важен, он указывает, какой ViewModel является вашим первым или основным экраном при запуске приложения.
[Export(Typeof(MainViewModel))]
public class MainViewModel : Screen, IShell
{
[ImportingConstructor]
public MainViewModel(YourFirstViewModel firstViewModel, YourSecondViewModel secondviewModel) // etc, for each child ViewModel
{
}
}
В [ImportingConstructor]
вам не нужноделать что-либо кроме указания, что MainViewModel требует присутствия других ViewModel.В моем конкретном случае мне нравится, что мой MainViewModel является контейнером, и только контейнером, логика событий обрабатывается в другом месте.Но вы могли бы также легко использовать здесь свою логику Handle - но это совсем другое обсуждение.
Теперь каждая дочерняя View View также должна экспортировать себя, чтобы CM знал, где их найти.
[Export(Typeof(YourFirstViewModel))]
public class YourFirstViewModel : IShell
{
// VM properties and events here
}
Нет необходимости указывать конструктор импорта, если вы просто используете конструктор по умолчанию.
Теперь каждый из ваших представлений для них будет выглядеть примерно так:
<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">
<StackPanel x:Name="RootVisual">
<views:YourFirstView />
<views:YourSecondView />
<!-- other controls as needed -->
</StackPanel>
</UserControl>
XAMl или один изthe child-views
<UserControl x:Class="Your.Namespace.Views.YourFirstView"
xmlns:cal="http://www.caliburnproject.org"
cal:Bind.Model="Your.Namespace.ViewModels.YourFirstViewModel"
MinWidth="800" MinHeight="600">
<Grid x:Name="RootVisual">
<!-- A bunch of controls here -->
</Grid>
</UserControl>
Какого черта здесь происходит на самом деле?
Хорошо, CM видит в загрузчике, что MainViewModel является отправной точкой из-за строки, указывающей public class AppBootstrapper : Bootstrapper<MainViewModel>
,MainViewModel
требует, чтобы YourFirstViewModel
и YourSecondViewModel
(и другие ViewModels) требовались в его конструкторе, поэтому CM конструирует каждый из них.Все эти ViewModel попадают в IoC (что значительно облегчает вашу жизнь позже - опять же, совершенно другое обсуждение).
CM обрабатывает присвоение текста данных от вашего имени каждому представлению, потому что вы указываете, какойВМ связывается с линией вроде cal:Bind.Model="Your.Namespace.ViewModels.YourFirstViewModel"
Если повезет, это поможет вам начать.Также обратитесь к примеру проекта CM Caliburn.Micro.HelloEventAggregator
, поскольку он делает именно то, что вы ищете (хотя он описан как демонстрация Event Aggregator, что также очень полезно - но опять же, другое обсуждение)
(ОригиналОтвет на почтение, ниже)
Вам необходимо сделать следующее:
<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">
<YourControlLayout />
</UserControl>
Обратите внимание на строку cal:Bind.Model="Your.Namespace.Here.YourViewModel"
, которая указывает точную модель вида, к которой привязывается этот вид.
Не забудьте экспортировать тип вашего класса, или cm не может его найти.
[Export(typeof(YourViewModel))]
public class YourViewModel : IShell
{
...
}
Тогда вы можете вкладывать свои пользовательские элементы управления по своему усмотрению.Это очень хороший способ использовать CM, и вы найдете его очень масштабируемым.Единственным недостатком является то, что View и ViewModel должны быть в одном проекте (насколько я могу судить).Но сила этого подхода в том, что вы можете разделить классы View и View Model на разные пространства имен (в рамках одного проекта), если хотите, чтобы все было организовано.
В качестве комментария к cm я предпочитаю этот метод,на самом деле, даже если мне не нужно вкладывать View UserControls и тому подобное.Я предпочел бы явно объявить, что с VM связан View (и все же позволить CM обрабатывать всю тяжелую работу в IoC), чем позволить cm «выяснить это» из подразумеваемого кода.
Даже с хорошей структурой: явныйкод более понятен, чем подразумеваемый код.Преимущество указания связанной модели представления состоит в том, что она четко указывает, каким должен быть ваш контекст данных, поэтому вам не нужно будет угадывать позже.