将动态加载的UserControl添加到AvalanDock MVVM方式

时间:2016-03-23 13:42:04

标签: c# wpf mvvm dll xceed

我有基于模块的应用程序,其中每个模块(.dll)包含一个主UserControl。模块仅在必要时加载,并且其UserControls被添加到MainWindow中。 主窗口使用AvalanDock [2.0]来对接模块的UserControls。到目前为止,我这样做:

public void DockUserControl(UserControl userControl){
    var documentPane = dockingManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
        if (documentPane != null)
            var layoutDocument = new LayoutDocument { Content = userControl };
            documentPane.Children.Add(layoutDocument);
            documentPane.SelectedContentIndex = documentPane.Children.IndexOf(layoutDocument);
}

这种模式非常有限,例如我想将layoutDocument的Title绑定到UserControl的ViewModel,处理结束事件等。因此我想使用MVVM模式。典型用法如下:

<avalonDock:DockingManager x:Name="dockManager" 
                           DocumentsSource="{Binding UserControls}">
    <avalonDock:DockingManager.LayoutItemTemplateSelector>
        ...
    </avalonDock:DockingManager.LayoutItemTemplateSelector>
    <avalonDock:DockingManager.LayoutItemContainerStyleSelector>
        ...
    </avalonDock:DockingManager.LayoutItemContainerStyleSelector>
...

但是,有很多模块,主窗口应该只知道它们有一些共同的祖先。因此,我无法在LayoutItemTemplateSelector中列出所有UserControl。我所拥有的是UserControls列表。

你有什么想法,如何使用MVVM和动态加载的UserControls?

1 个答案:

答案 0 :(得分:0)

就我而言,我有:

public ObservableCollection<EditorViewModel> Documents { get; }

在XAML中

<avalonDock:DockingManager x:Name="dockingManager" DocumentsSource="{Binding Documents}" ....

然后我说那个viewmodel的视图是什么

<avalonDock:DockingManager.Resources>
            <!-- View with its vm -->
            <DataTemplate DataType="{x:Type editor:EditorViewModel}">
                <editor:EditorView />
            </DataTemplate>
</avalonDock:DockingManager.Resources>

最后,我为标题和其他属性添加了绑定:

 <avalonDock:DockingManager.LayoutItemContainerStyle>
            <Style TargetType="{x:Type avalonDock:LayoutItem}">  <!-- these properties are in its own vm (EditorViewModel instance)-->
                <Setter Property="Title" Value="{Binding Model.Title}" />
                <Setter Property="IsSelected" Value="{Binding Model.IsSelected,Mode=TwoWay}" />
                <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
            </Style>
        </avalonDock:DockingManager.LayoutItemContainerStyle>

在我看来,你可以有一个基本的ViewModel用于绑定,然后每个用户控件都可以扩展它。

我希望这可以帮到你。