我对Caliburn Micro及其使用的范例很熟悉,但现在正在尝试集成AvalonDock。
作为POC,我有一个非常简单的应用程序,其 shell View 模型包含一个可激活我的StructureViewModels的按钮-一个包含名称和标题的简单类。该结构的 View 是一个用户控件,它仅将名称显示为文本。
使用Caliburn,ViewModels和Views可以很好地进行连接,并且将它们显示在Docking Manager中。我可以拖动和分离,枚举 Pane 等。-所有Avalon功能似乎都可以使用。我的问题是,它们在Avalon页眉(选项卡)中显示时没有标题。
ShellViewModel:
using AvalonDemo.Properties;
using Caliburn.Micro;
namespace AvalonDemo.ViewModels
{
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
private int _structureCount;
public ShellViewModel()
{
WindowTitle = Resources.MainWindowTitle;
_structureCount = 1;
}
public string WindowTitle { get; set; }
public void OpenStructure()
{
ActivateItem(new StructureViewModel
{
Name = "Structure" + _structureCount++,
Title = "Structure" + _structureCount
});
}
}
}
已编辑解决方案:
ShellView:
<Window x:Class="AvalonDemo.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avalonDock="http://schemas.xceed.com/wpf/xaml/avalondock"
xmlns:cal="http://www.caliburnproject.org"
xmlns:common="clr-namespace:AvalonDemo.Common"
Title="{Binding WindowTitle}"
Height="850" Width="1200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button x:Name="OpenStructure" Grid.Row="0" Width="50">Open</Button>
<avalonDock:DockingManager
Grid.Row="1" x:Name="DockingManager"
DocumentsSource="{Binding Items}">
<avalonDock:DockingManager.LayoutItemContainerStyle>
<Style TargetType="{x:Type avalonDock:LayoutItem}">
<Setter Property="Title" Value="{Binding Model.Title}" />
</Style>
</avalonDock:DockingManager.LayoutItemContainerStyle>
<avalonDock:DockingManager.LayoutItemTemplateSelector>
<common:AutobinderTemplateSelector>
<common:AutobinderTemplateSelector.Template>
<DataTemplate>
<ContentControl cal:View.Model="{Binding . }" IsTabStop="False" />
</DataTemplate>
</common:AutobinderTemplateSelector.Template>
</common:AutobinderTemplateSelector>
</avalonDock:DockingManager.LayoutItemTemplateSelector>
<avalonDock:LayoutRoot>
<avalonDock:LayoutPanel Orientation="Horizontal">
<avalonDock:LayoutDocumentPaneGroup>
<avalonDock:LayoutDocumentPane />
</avalonDock:LayoutDocumentPaneGroup>
</avalonDock:LayoutPanel>
</avalonDock:LayoutRoot>
</avalonDock:DockingManager>
</Grid>
</Window>
StructureViewModel:
using Caliburn.Micro;
namespace AvalonDemo.ViewModels
{
public class StructureViewModel : Screen
{
public string Name { get; set; }
public string Title { get; set; }
}
}
StructureView:
<UserControl x:Class="AvalonDemo.Views.StructureView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<TextBlock Text="{Binding Path=Name}" />
</Grid>
</UserControl>
最后,我使用Autobinder选择DataTemplates:
using System.Windows;
using System.Windows.Controls;
namespace AvalonDemo.Common
{
public class AutobinderTemplateSelector : DataTemplateSelector
{
public DataTemplate Template { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return Template;
}
}
}
我试图将代码限制到最少,只是为了使POC正常工作,但是还没有看到使用Caliburn处理事件VM和Avalon Dock 2.0的许多(任何示例)工作示例。
提前致谢。
最佳答案
噢,我的人,昨晚花了很长时间尝试事情,当我发布问题时,我就找到了答案(StackOverflow-橡皮鸭?)
希望对其他人有所帮助,我只需要在Shell View 中添加一个LayoutItemContainerStyle即可告诉Avalon从何处获取Title:
<avalonDock:DockingManager.LayoutItemContainerStyle>
<Style TargetType="{x:Type avalonDock:LayoutItem}">
<Setter Property="Title" Value="{Binding Model.Title}" />
</Style>
</avalonDock:DockingManager.LayoutItemContainerStyle>