Joh*_*ara 5 c# wpf binding mvvm avalondock
我需要在 AvalonDock 2.0 中加载一组项目作为文档。这些对象从一个抽象类继承,我想根据子类在文档中呈现一个框架。
这是我的 XAML:
<ad:DockingManager Background="Gray" DocumentsSource="{Binding Path=OpenProjects}"
ActiveContent="{Binding Path=CurrentProject, Mode=TwoWay}">
<ad:DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=OpenProjects/Name}" />
</DataTemplate>
</ad:DockingManager.DocumentHeaderTemplate>
<ad:DockingManager.LayoutItemTemplate>
<DataTemplate>
<Grid>
<Grid.Resources>
<DataTemplate DataType="{x:Type vm:SubclassAViewModel}">
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SubclassBViewModel}">
<Frame Source="Pages/SubclassBProject.xaml" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SubclassCViewModel}">
<Frame Source="Pages/SubclassCProject.xaml" />
</DataTemplate>
</Grid.Resources>
</Grid>
</DataTemplate>
</ad:DockingManager.LayoutItemTemplate>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane>
</ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经实现了显示与OpenProjects集合中项目一样多的文档,但我似乎无法在每个文档中显示任何内容。
另外,我不知道我ActiveContent是否正确使用:我想分配给CurrentProject当前活动文档上分配的 ViewModel。
感谢您的时间。
您看不到任何内容的原因是您定义LayoutItem模板的方式。这是行不通的。
还可以考虑使用自定义控件而不是Frame. 非常Frame重。除非您不需要显示 HTML,否则请避免使用此控件。如果您想显示可导航的内容,内容导航非常容易实现。只需将您的文档内容包装到UserControl.
您正在ActiveContent正确使用该财产。
为了解决您的问题,您有三个推荐的解决方案,其中第一个并不能完全满足您的要求。既然你定义DockingManager.LayoutItemTemplate错了,我无论如何都会展示它。
LayoutItemTemplate如果您只需要为所有容器使用一个模板LayoutDocument,LayoutAnchorable则可以使用该DockingManager.LayoutItemTemplate属性。此属性接受单个DataTemplate. DataTemplateWPF 通常不支持嵌套定义(如代码中的嵌套定义)。
<ad:DockingManager>
<ad:DockingManager.LayoutItemTemplate>
<DataTemplate>
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
</ad:DockingManager.LayoutItemTemplate>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane />
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
Run Code Online (Sandbox Code Playgroud)
DataTemplate在更高级的场景中,您可以根据不同的模型显示不同的视图。如果显示的内容仅取决于模型的数据类型(如您的情况),建议的方法是提供隐式DataTemplate定义。
WPF 将自动将隐式应用DataTemplate到与此模板匹配的每个数据类型DataTemplate.TargetType。如果没有明确指定值,
则是隐式的。为了确保实际上可以自动应用 ,还必须在与目标类型相同的资源范围中定义 。例如,定义App.xaml中的in将使模板自动应用到应用程序范围中。DataTemplatex:KeyDataTemplateDataTemplateDataTemplateApplication.Resources
<ad:DockingManager>
<ad:DockingManager.Resources>
<DataTemplate DataType="{x:Type vm:SubclassAViewModel}">
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SubclassBViewModel}">
<Frame Source="Pages/SubclassBProject.xaml" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SubclassCViewModel}">
<Frame Source="Pages/SubclassCProject.xaml" />
</DataTemplate>
</ad:DockingManager.Resources>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane>
</ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
Run Code Online (Sandbox Code Playgroud)
DataTemplateSelector以前的解决方案使用隐式DataTemplate定义,可以用DataTemplateSelector. DataTemplateSelector是选择性应用的另一个 WPF 概念DataTemplate。如果选择 A可能取决于比单独模型的数据类型更复杂的约束,则建议选择
A。它允许评估数据项并根据某些标准选择适当的模板。DataTemplateSelectorDataTemplate
要定义模板选择器,您必须扩展DataTemplateSelector,它预计返回一个DataTemplate. 最简单的方法是使用 定义App.xaml资源字典
中的模板,然后根据条件从中进行选择。通过分配属性接受模板选择器:x:Key
DockingMangerDockingManager.LayoutItemTemplateSelector
App.xaml
定义显式DataTemplate使用x:Key:
<Application.Resources>
<DataTemplate x:Key="SubclassAViewModelTemplate" DataType="{x:Type vm:SubclassAViewModel}">
<Frame Source="Pages/SubclassAProject.xaml" />
</DataTemplate>
<DataTemplate x:Key="SubclassBViewModelTemplate" DataType="{x:Type vm:SubclassBViewModel}">
<Frame Source="Pages/SubclassBProject.xaml" />
</DataTemplate>
<DataTemplate x:Key="SubclassCViewModelTemplate" DataType="{x:Type vm:SubclassCViewModel}">
<Frame Source="Pages/SubclassCProject.xaml" />
</DataTemplate>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
DocumentManagerTemplateSelector.cs
以下代码使用 Switch 表达式,该表达式自 C# 8.0 起可用。它可以用 switch 语句或级联 if 语句替换。
class DocumentManagerTemplateSelector : DataTemplateSelector
{
#region Overrides of DataTemplateSelector
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return item switch
{
SubclassAViewModel _ => Application.Current.Resources["SubclassAViewModelTemplate"] as DataTemplate,
SubclassBViewModel _ => Application.Current.Resources["SubclassBViewModelTemplate"] as DataTemplate,
SubclassCViewModel _ => Application.Current.Resources["SubclassCViewModelTemplate"] as DataTemplate,
_ => base.SelectTemplate(item, container)
};
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
主窗口.xaml
<ad:DockingManager>
<xcad:DockingManager.LayoutItemTemplateSelector>
<local:DocumentManagerTemplateSelector />
</xcad:DockingManager.LayoutItemTemplateSelector>
<ad:LayoutRoot>
<ad:LayoutPanel>
<ad:LayoutDocumentPaneGroup>
<ad:LayoutDocumentPane>
</ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
</ad:LayoutPanel>
</ad:LayoutRoot>
</ad:DockingManager>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
541 次 |
| 最近记录: |