AvalonDock MVVM动态视图

时间:2019-05-07 13:29:31

标签: c# mvvm prism avalondock

我正在使用Xceed.Wpf.AvalonDock软件包(版本3.5)中的AvalonDock。对接管理器是我主要观点的一部分。有趣的部分在这里:

    <xcad:DockingManager Name="_dockingManager" Grid.Row="1" DataContext="{Binding DockingManagerViewModel}"
                     DocumentsSource="{Binding Documents}"
                     AnchorablesSource="{Binding Anchorables}" >

        <xcad:DockingManager.Resources>

            <DataTemplate DataType="{x:Type vm:DockingWindowViewModel}">
                <v:SampleDockWindowView />
            </DataTemplate>

        </xcad:DockingManager.Resources>

        <xcad:DockingManager.LayoutItemContainerStyle>
            <Style TargetType="{x:Type dockctrl:LayoutItem}" >
                <Setter Property="Title" Value="{Binding Model.Title}" />
                <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
                <Setter Property="CanClose" Value="{Binding Model.CanClose}" />
            </Style>
        </xcad:DockingManager.LayoutItemContainerStyle>

    </xcad:DockingManager>

因此,主视图模型包含一个可观察的集合(例如“文档”),我可以在其中动态添加视图模型。现在的问题是,对于不同的视图模型,我具有不同的视图,并且这些视图将在运行时添加。当前,视图是根据数据模板检索的:

    <xcad:DockingManager.Resources>

        <DataTemplate DataType="{x:Type vm:DockingWindowViewModel}">
            <v:SampleDockWindowView />
        </DataTemplate>

    </xcad:DockingManager.Resources>

如何更改此设置以根据相应的视图模型获得动态视图?

2 个答案:

答案 0 :(得分:0)

视图到视图模型通常是一对一的映射,因此只需从xaml或从代码或两者的组合中添加很多DataTemplate ...(每个模块和代码xaml在模块初始化程序中,将模块的ResourceDictionary合并到应用程序中)。

答案 1 :(得分:0)

有些人已经在这里回答,因此您需要添加模板选择器。 因此,一个例子可能会驱使您。

假设您有两个名为

的视图/视图模型

MyDocViewA -> MyDocAViewModel

MyDocViewB -> MyDocBViewModel

在主视图XAML代码上的DockingManager代码中,您需要像这样添加LayoutItemTemplateSelector

                <xcad:DockingManager.LayoutItemTemplateSelector>
                <s:PanesTemplateSelector>
                    <s:PanesTemplateSelector.MyDocViewATemplate>
                        <DataTemplate>
                            <p:MyDocViewA />
                        </DataTemplate>
                    </s:PanesTemplateSelector.MyDocViewATemplate>
                    <s:PanesTemplateSelector.MyDocViewBTemplate>
                        <DataTemplate>
                            <p:MyDocViewB />
                        </DataTemplate>
                    </s:PanesTemplateSelector.MyDocViewBTemplate>                        
            </xcad:DockingManager.LayoutItemTemplateSelector>

其中s是定义PanesTemplateSelector的命名空间,如下所示:

    class PanesTemplateSelector : DataTemplateSelector
{
    public DataTemplate MyDocViewATemplate { get; set; }
    public DataTemplate MyDocViewBTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is MyDocAViewModel)
            return MyDocViewATemplate;

        if (item is MyDocBViewModel)
            return MyDocViewBTemplate;
    }
}

假定视图{{1}的MyDocAViewModelViewModel,视图MyDocViewA的{​​{1}}是MyDocBViewModel

就是这样。现在,您可以将ViewModelMyDocViewB的实例添加到MyDocAViewModel的可观察集合(例如“文档”)中,并将其绑定到MyDocBViewModel和{{1} }。