我有基于模块的应用程序,其中每个模块(.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?
答案 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用于绑定,然后每个用户控件都可以扩展它。
我希望这可以帮到你。