Caliburn.Micro 自定义 ViewModelLocator:在 ItemContainerStyle 中绑定用户控件 属性

Caliburn.Micro custom ViewModelLocator: bind usercontrol property in ItemContainerStyle

我正在使用 Xceed 工具包 WindowContainer 和 ChildWindows 生成由多个 windows(容器)组成的动态客户区,每个容器包含多个自定义用户控件(元素)。这些 windows 可以在 WindowContainer 区域中自由移动、调整大小和最大化。

为了在 ViewModel 级别表示层次结构,我使用 Caliburn.Micros 导体机制。 所以 MainViewModel 进行容器:

public class MainViewModel : Conductor<ElementContainerViewModel>.Collection.AllActive

并且容器传导元素:

public class ElementContainerViewModel : Conductor<ElementViewModel>.Collection.AllActive

相应的视图如下所示(自定义项控件用 ChildWindow 作为容器替换默认的 ContentPresenter)。 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}" />

绑定工作正常,但没有正确附加相应的视图。所以我只是添加了一个老式的数据模板来将容器 ViewModel 绑定到它对应的视图:

<DataTemplate DataType="{x:Type viewModels:ElementContainerViewModel}">
   <views:ElementContainerView />
</DataTemplate>

问题:由于 ViewModel 定位器进程不再由 Caliburn.Micro 完成,关闭应用程序会导致每个 ChildWindow 出现 nullreference 异常,这是由 Caliburn.Micro 关闭执行的 ViewModels 引起的,但不关闭 ElementContainerView。

如何告诉 Caliburn.Micro 像我在数据模板中所做的那样解决该约定。 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");

非常感谢, 李

您是否尝试过使用 cal:View.Model="{Binding}" 而不是 DataTemplate 来告诉 caliburns 视图绑定引擎查找模型的视图?