Stalker
Stalker

Reputation: 688

Using AvalonDock with Caliburn Micro

I'm trying to use AvalonDock 2.8 together with Caliburn Micro 2.0.2. Here is what I currently have:

MainView.xaml:

<Window x:Class="MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:cal="http://www.caliburnproject.org"
        xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
        xmlns:local="clr-namespace:CaliburnMicroAndAvalonDock"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Button x:Name="Open" Content="Open new document" Margin="5"/>

        <xcad:DockingManager Grid.Row="1" DocumentsSource="{Binding Items}">
            <xcad:DockingManager.LayoutItemContainerStyle>
                <Style TargetType="{x:Type xcad:LayoutItem}">
                    <Setter Property="Title" Value="{Binding Model.DisplayName}" />
                </Style>
            </xcad:DockingManager.LayoutItemContainerStyle>

            <xcad:DockingManager.LayoutItemTemplateSelector>
                <local:LayoutItemTemplateSelector>
                    <local:LayoutItemTemplateSelector.Template>
                        <DataTemplate>
                            <ContentControl cal:View.Model="{Binding .}" IsTabStop="False"/>
                        </DataTemplate>
                    </local:LayoutItemTemplateSelector.Template>
                </local:LayoutItemTemplateSelector>
            </xcad:DockingManager.LayoutItemTemplateSelector>

            <xcad:LayoutRoot>
                <xcad:LayoutPanel Orientation="Horizontal">
                    <xcad:LayoutDocumentPane/>
                </xcad:LayoutPanel>
            </xcad:LayoutRoot>
        </xcad:DockingManager>
    </Grid>
</Window>

MainViewModel.vb:

Imports Caliburn.Micro

Public Class MainViewModel
  Inherits Conductor(Of Screen).Collection.OneActive

  Private m_Index As Int32 = 0

  Sub Open()
    ActivateItem(New DocumentViewModel With {.DisplayName = $"Document {m_Index}"})
    m_Index += 1
  End Sub

End Class

Document.xaml:

<UserControl x:Class="DocumentView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:CaliburnMicroAndAvalonDock"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBlock Text="{Binding DisplayName}"/>
    </Grid>
</UserControl>

DocumentViewModel.vb:

Imports Caliburn.Micro

Public Class DocumentViewModel
  Inherits Screen

End Class

LayoutItemTemplateSelector.vb:

Public Class LayoutItemTemplateSelector
  Inherits DataTemplateSelector

  Public Property Template As DataTemplate

  Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
    Return Me.Template
  End Function

End Class

Partially it works, problem is that view fails to load with Cannot find view for System.Windows.Controls.ContentPresenter error:

Error

I'm quite new to both Caliburn Micro and AvalonDock, so my code is heavily based on examples I found online (e.g. this). But those samples are quite old and it doesn't work with current version of AvalonDock (2.8.15465.16500). If I switch to older one (2.0.2000), it works fine.

Upvotes: 0

Views: 853

Answers (1)

Stalker
Stalker

Reputation: 688

I managed to solve this problem with help of this answer and this explanation. Here is updated code of LayoutItemTemplateSelector.vb:

Public Class LayoutItemTemplateSelector
  Inherits DataTemplateSelector

  Public Property Template As DataTemplate

  Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
    If TypeOf item Is DocumentViewModel Then
      Return Me.Template
    Else
      Return MyBase.SelectTemplate(item, container)
    End If
  End Function

End Class

Upvotes: 2

Related Questions