Caliburn.Micro custom ViewModelLocator: связать свойство usercontrol в ItemContainerStyle
Я использую инструментарий Xceed WindowContainer и ChildWindows для создания динамической клиентской области, состоящей из нескольких окон (контейнера), каждое из которых содержит несколько пользовательских элементов управления (элементов). Эти окна можно свободно перемещать, изменять их размер и максимизировать в области WindowContainer.
Для представления иерархии на уровне 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:
<Setter Property="xctk:ChildWindow.Content" Value="{Binding}" />
Привязка работает нормально, но соответствующий вид не прикреплен должным образом. Поэтому я просто добавил старомодную табличку данных для привязки контейнера ViewModel к соответствующему представлению:
<DataTemplate DataType="{x:Type viewModels:ElementContainerViewModel}">
<views:ElementContainerView />
</DataTemplate>
Проблема: поскольку процесс локатора ViewModel больше не выполняется Caliburn.Micro, закрытие приложения приводит к исключению nullreference для каждого ChildWindow, которое вызывается Caliburn.Micro, закрывающим проводимые ViewModels, но не закрывающим ElementContainerView.
Как я могу сказать Caliburn.Micro, чтобы решить эту конвенцию, как я делаю в табличке данных. Представления и 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");
Большое спасибо, Ли
1 ответ
Вместо DataTemplate пытались ли вы использовать cal:View.Model="{Binding}"
сказать калибрующему движку привязки вида для поиска вида для модели?