Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avalon Dock and Caliburn Micro - no title on document pane (tab header)

I am familiar with Caliburn Micro and the paradigms it uses, but am now trying to integrate AvalonDock.

As a POC, I have a very simple app with a shell view model containing a button which activates my StructureViewModels - a simple class containing a name and a title. The view for the structure is a user control which just displays the name as text.

The ViewModels and Views are hooking up nicely using Caliburn and they are being displayed in the Docking Manager. I can drag and detach, enumerate panes etc. - all the Avalon features seem to work. The problem I have is that they are displayed without the title in the Avalon Header (tab).

Screenshot

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
            });
        }
    }
}

Edited with solution:

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>

Finally, I am using an Autobinder to select 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;
        }
    }
} 

I have tried to limit code to the minimum just to get a POC working, but haven't seen many (any?) working examples using Caliburn to handle active VMs and Avalon Dock 2.0.

Thanks in advance.

like image 535
WillH Avatar asked Oct 21 '22 07:10

WillH


1 Answers

Oh my, I spent ages trying things last night and as soon as I posted the question, I found the answer (StackOverflow-rubber duck?)

In the hope that this helps someone else, I just needed a LayoutItemContainerStyle adding to the shell view to tell Avalon where to get the Title from:

<avalonDock:DockingManager.LayoutItemContainerStyle>
     <Style TargetType="{x:Type avalonDock:LayoutItem}">
          <Setter Property="Title" Value="{Binding Model.Title}" />
     </Style>
</avalonDock:DockingManager.LayoutItemContainerStyle>
like image 141
WillH Avatar answered Nov 11 '22 16:11

WillH