Я использую инструментарий Xceed WindowContainer и ChildWindows для создания динамической клиентской области, состоящей из нескольких окон (контейнеров), каждая из которых содержит несколько пользовательских элементов управления (элементов). Эти окна можно свободно перемещать, изменять размер и максимизировать в области WindowContainer.Caliburn.Micro custom ViewModelLocator: связать свойство usercontrol в ItemContainerStyle
Чтобы представить иерархию на уровне ViewModel, я использую проводящий механизм Caliburn.Micros. Так MainViewModel проводит контейнеры:
public class MainViewModel : Conductor<ElementContainerViewModel>.Collection.AllActive
и контейнер ведет элементы:
public class ElementContainerViewModel : Conductor<ElementViewModel>.Collection.AllActive
Соответствующие виды выглядеть следующим образом (контроль пользовательского элемента для замены ContentPresenter по умолчанию с ChildWindow в контейнере) , MainView.xaml (ElementContainerView.xaml опущены для краткости):
<childWindowContainer:MyItemsControl x:Name="Items" >
<childWindowContainer:MyItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<xctk:WindowContainer Height="800" Width="600" Background="LightGoldenrodYellow"/>
</ItemsPanelTemplate>
</childWindowContainer:MyItemsControl.ItemsPanel>
<childWindowContainer:MyItemsControl.ItemContainerStyle>
<Style>
<Setter Property="xctk:ChildWindow.Left" Value="{Binding ContainerLeft}" />
<Setter Property="xctk:ChildWindow.Top" Value="{Binding ContainerTop}" />
<Setter Property="xctk:ChildWindow.Width" Value="{Binding ContainerWidth}" />
<Setter Property="xctk:ChildWindow.Height" Value="{Binding ContainerHeight}" />
<Setter Property="xctk:ChildWindow.CloseButtonVisibility" Value="Collapsed" />
<Setter Property="xctk:ChildWindow.Content" Value="{Binding}" />
<Setter Property="xctk:ChildWindow.IsMaximized" Value="{Binding IsMaximized, Mode=TwoWay}" />
</Style>
</childWindowContainer:MyItemsControl.ItemContainerStyle>
</childWindowContainer:MyItemsControl>
Линия, которая вызывает у меня головную боль является следующее, взятое из MainView ItemsControl:
<Setter Property="xctk:ChildWindow.Content" Value="{Binding}" />
связывания работает отлично, но соответствующее представление не прилагается должным образом. Так что я просто добавил старомодный DataTemplate связать контейнер ViewModel с соответствующим видом:
<DataTemplate DataType="{x:Type viewModels:ElementContainerViewModel}">
<views:ElementContainerView />
</DataTemplate>
Проблема: поскольку процесс локатора ViewModel не делается Caliburn.Micro больше, закрытие приложения приводит к исключение nullreference для каждого ChildWindow, вызванное Caliburn.Micro закрытие ведомых ViewModels, но не закрытие ElementContainerView.
Как я могу сказать Caliburn.Micro, чтобы разрешить это соглашение, как я делаю в datatemplate. Модели Views и ViewModels, конечно, правильно организованы, поэтому могут использоваться стандартные соглашения (RootNS.ViewModels.ElementContainerViewModel.cs/RootNS.Views.ElementContainerView.xaml). Я искал с помощью ViewLocator.NameTransformer и ConventionManager, но не смог заставить его работать.
ConventionManager.AddElementConvention<ChildWindow>(ContentControl.ContentProperty, "Content",
"DataContextChanged");
ViewLocator.NameTransformer.AddRule(@"^ElementContainerViewModel", @"ChildWindowContainer.Views.ElementContainerView");
Большое спасибо, Ly
После того, как я разместил здесь вопрос, я понял, что есть другой синтаксис Caliburn.Micro привязки. Я добавил именно ту линию, которую вы предложили, и она просто работает. Так что да, это решение! Большое вам спасибо, я приму ваше предложенное решение в качестве ответа. –