AvalonDock - prevent anchorable pane docking in document pane
Is it possible to prevent an anchorable being docked into my documents pane? I want them to be draggable and moved around the screen, but sometimes users drag them into the documents pane which makes them look poor. Then they close the tab and I can't re-open the anchorable.
If it helps my Avalon code is below:
<avalonDock:DockingManager.Theme>
<avalonDock:VS2010Theme />
</avalonDock:DockingManager.Theme>
<avalonDock:DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<!-- the TextBlock named Limiter is used to limit the height of the TextBlock for the workflow name. -->
<TextBlock x:Name="Limiter" TextWrapping="NoWrap" Visibility="Hidden"
TextTrimming="CharacterEllipsis">
L
</TextBlock>
<TextBlock Text="{Binding Path=Title}" VerticalAlignment="Center"
ToolTip="{StaticResource WorkflowTabItemToolTip}"
MaxHeight="{Binding ActualHeight, ElementName=Limiter}" MaxWidth="150"
TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Margin="0,0,2,0"
AutomationProperties.AutomationId="WorkflowTabTitleText"/>
<TextBlock Text=" *"
ToolTip="Has unsaved changes"
Visibility="{Binding Content.UnsavedEdits, Converter={StaticResource BoolToVis}}"
AutomationProperties.AutomationId="DirtyTabIndicator"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</avalonDock:DockingManager.DocumentHeaderTemplate>
<avalonDock:DockingManager.LayoutItemContainerStyleSelector>
<utilities1:PanesStyleSelector>
<utilities1:PanesStyleSelector.WebUIStyle>
<Style TargetType="{x:Type avalonDock:LayoutAnchorableItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<Setter Property="IconSource" Value="{Binding Model.IconSource}"/>
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter={x:Static Visibility.Hidden}}"/>
<Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/>
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
</Style>
</utilities1:PanesStyleSelector.WebUIStyle>
<utilities1:PanesStyleSelector.DocumentStyle>
<Style TargetType="{x:Type avalonDock:LayoutItem}">
<Setter Property="Title" Value="{Binding Model.WorkflowName}" />
<Setter Property="IsActive" Value="{Binding Model.IsActive}" />
<Setter Property="IsSelected" Value="{Binding Model.IsActive}" />
</Style>
</utilities1:PanesStyleSelector.DocumentStyle>
</utilities1:PanesStyleSelector>
</avalonDock:DockingManager.LayoutItemContainerStyleSelector>
<avalonDock:DockingManager.LayoutItemTemplateSelector>
<utilities1:PanesTemplateSelector>
<utilities1:PanesTemplateSelector.WorkflowDesignerViewTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" IsTabStop="False" />
</DataTemplate>
</utilities1:PanesTemplateSelector.WorkflowDesignerViewTemplate>
<utilities1:PanesTemplateSelector.WebUIViewTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" IsTabStop="False" />
</DataTemplate>
</utilities1:PanesTemplateSelector.WebUIViewTemplate>
</utilities1:PanesTemplateSelector>
</avalonDock:DockingManager.LayoutItemTemplateSelector>
<avalonDock:LayoutRoot>
<avalonDock:LayoutPanel Orientation="Horizontal">
<avalonDock:LayoutDocumentPaneGroup>
<avalonDock:LayoutDocumentPane AutomationProperties.AutomationId="AvalonDocumentPane"/>
</avalonDock:LayoutDocumentPaneGroup>
<avalonDock:LayoutAnchorablePane DockWidth="800" DockMinWidth="400" AutomationProperties.AutomationId="WebUIPane"/>
<avalonDock:LayoutAnchorablePane DockWidth="225" DockMinWidth="225" AutomationProperties.AutomationId="ActivitiesPane">
<avalonDock:LayoutAnchorable Title="Activities" AutoHideWidth="225" AutoHideMinWidth="225" CanClose="False" CanHide="False">
<toolbox:ToolboxControl Name="Toolbox" AutomationProperties.AutomationId="ActivitiesToolbox"
utilities1:ToolboxItemSource.ToolboxItems="{Binding ToolboxList}" />
</avalonDock:LayoutAnchorable>
</avalonDock:LayoutAnchorablePane>
</avalonDock:LayoutPanel>
</avalonDock:LayoutRoot>
</avalonDock:DockingManager>
Although I didn't find a direct way of preventing the docking, I was able to get the basic problem fixed, namely customizing different tab headers for tool windows and document windows. My document windows show asterisk (*) in the tab header to indicate changes (just like VS), whereas the tool windows should not do so.
The solution was to use DocumentHeaderTemplateSelector
and provide it with two different templates, one each for documents and tool windows. Here's the XAML:
<xcad:DockingManager.DocumentHeaderTemplateSelector>
<bd:DocumentHeaderTemplateSelector>
<bd:DocumentHeaderTemplateSelector.DocumentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Resources\AppIcon.ico" Margin="0,0,4,0" Width="16" />
<TextBlock Text="{Binding Title}" />
<TextBlock Text=" *" Visibility="{Binding Content.IsDirty, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
</DataTemplate>
</bd:DocumentHeaderTemplateSelector.DocumentTemplate>
<bd:DocumentHeaderTemplateSelector.ToolWindowTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</bd:DocumentHeaderTemplateSelector.ToolWindowTemplate>
</bd:DocumentHeaderTemplateSelector>
</xcad:DockingManager.DocumentHeaderTemplateSelector>
The selector class is simply:
Public Class DocumentHeaderTemplateSelector
Inherits DataTemplateSelector
Public Property DocumentTemplate As DataTemplate
Public Property ToolWindowTemplate As DataTemplate
Public Overrides Function SelectTemplate(item As Object, container As System.Windows.DependencyObject) As System.Windows.DataTemplate
Dim itemAsLayoutContent = TryCast(item, Xceed.Wpf.AvalonDock.Layout.LayoutContent)
If TypeOf item Is Xceed.Wpf.AvalonDock.Layout.LayoutDocument AndAlso TypeOf DirectCast(item, Xceed.Wpf.AvalonDock.Layout.LayoutDocument).Content Is DocumentVM Then
Return DocumentTemplate
Else
Return ToolWindowTemplate
End If
End Function
End Class
Now my tool windows do not show asterisk (*) and icon even if they are moved into the documents pane.
Hope this helps someone down the road.