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}" сказать калибрующему движку привязки вида для поиска вида для модели?

Другие вопросы по тегам