Search code examples
c#wpfxamlmvvmavalondock

AvalonDock - How to disable autohide capability for all anchorables


I'm hoping to remove the "AutoHide" capability from my usage of AvalonDock. I modeled my solution after this example here: http://lostindetails.com/blog/post/AvalonDock-2.0-with-MVVM

My current thought process is that if I can remove the option from both the tab (the symbol next to the "closing X") and the context menu, users won't be able to perform a hide operation. If there is another way to accomplish the removal of the hide operation, that would work as well.

Removing Hide From Tab and Context Menu

In the example, he is able to set the CanClose property on a LayoutItem, thus affecting any item that is displayed due to being inside the DocumentsSource. I would like to do the same thing, but for CanHide and CanAutoHide and have it affect Anchorables inside my AnchorablesSource.

Edit: I have added the line:

<Setter Property="dockctrl:LayoutAnchorableItem.CanHide" Value="False" />

which now gets me half way there. This line removes the hide ability, however it does not remove the "AutoHide" pin symbol (or the context menu option). I know the CanAutoHide property does exist, I'm just not sure how to set it. Here are the relevant docs from Xceed

Current Solution

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>


        <dock:DockingManager x:Name="AvalonDockDockingManager" Grid.Row="1"
                    AllowMixedOrientation="True"
                    DataContext="{Binding DockManagerViewModel}"
                    DocumentsSource="{Binding Documents}"
                    AnchorablesSource="{Binding Anchorables}" >

            <dock:DockingManager.Resources>
            </dock:DockingManager.Resources>

            <dock:DockingManager.LayoutItemContainerStyle>
                <Style TargetType="{x:Type dockctrl:LayoutItem}" >
                    <Setter Property="Title" Value="{Binding Model.Title}" />
                    <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
                    <Setter Property="CanClose"  Value="{Binding Model.CanClose}" />
                    <Setter Property="dockctrl:LayoutAnchorableItem.CanHide" Value="False" />


                </Style>
            </dock:DockingManager.LayoutItemContainerStyle>



            <dock:DockingManager.AnchorablePaneControlStyle>
                <Style TargetType="{x:Type dockctrl:LayoutAnchorableItem}" >
                    <Setter Property="CanHide"  Value="False" />
                </Style>
            </dock:DockingManager.AnchorablePaneControlStyle>



        </dock:DockingManager>
    </Grid>

Solution

    1. You will have to re-style some elements of AvalonDock to get rid of the AutoHide pin. Below is a sample XAML of the AchorablePaneTitle style taken from the Generic.xaml.

    2. As alternative solution: You can also let the Pin dissappear by setting CanAutoHide="False" and CanHide="False" in this sample application.

    The changed XAML looks like this

    <avalonDock:LayoutAnchorable x:Name="WinFormsWindow"
                                 ContentId="WinFormsWindow"
                                 Title="WinForms Window"
                                 ToolTip="My WinForms Tool"
                                 CanAutoHide="False"
                                 CanHide="False"
                                 CanClose="False" >
        <winformsIntegration:WindowsFormsHost x:Name="winFormsHost" Background="White"/>
    </avalonDock:LayoutAnchorable>
    

    This is the screenshot taken from the linked sample application above. Note the missing pin on the Winforms Window. enter image description here

    Override the AnchorablePaneTitle style to get rid of the pin defined in PART_AutoHidePin (eg.: Set Visibility = "Collapsed" on it).

      <Style TargetType="avalonDockControls:AnchorablePaneTitle">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate>
              <Border Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}">
                <Grid>
                  <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                  </Grid.ColumnDefinitions>
                  <avalonDockControls:DropDownControlArea DropDownContextMenu="{Binding Model.Root.Manager.AnchorableContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
                                                          DropDownContextMenuDataContext="{Binding Path=LayoutItem, RelativeSource={RelativeSource TemplatedParent}}">
                    <ContentPresenter Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
                                      ContentTemplate="{Binding Model.Root.Manager.AnchorableTitleTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                                      ContentTemplateSelector="{Binding Model.Root.Manager.AnchorableTitleTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}" />
                  </avalonDockControls:DropDownControlArea>
    
                  <avalonDockControls:DropDownButton Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}"
                                                     Focusable="False"
                                                     Grid.Column="1"
                                                     DropDownContextMenu="{Binding Model.Root.Manager.AnchorableContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
                                                     DropDownContextMenuDataContext="{Binding Path=LayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
                                                     ToolTip="{x:Static avalonDockProperties:Resources.Anchorable_CxMenu_Hint}">
                    <Border Background="White">
                      <Image Source="/Xceed.Wpf.AvalonDock;component/Themes/Generic/Images/PinMenu.png">
                      </Image>
                    </Border>
                  </avalonDockControls:DropDownButton>
    
                  <Button x:Name="PART_AutoHidePin"
                          Grid.Column="2"
                          Focusable="False"
                          Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
                          Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
                          Command="{Binding Path=LayoutItem.AutoHideCommand, RelativeSource={RelativeSource TemplatedParent}}"
                          ToolTip="{x:Static avalonDockProperties:Resources.Anchorable_BtnAutoHide_Hint}">
                    <Border Background="White">
                      <Image Source="/Xceed.Wpf.AvalonDock;component/Themes/Generic/Images/PinAutoHide.png">
                      </Image>
                    </Border>
                  </Button>
    
                  <Button x:Name="PART_HidePin"
                          Grid.Column="3"
                          Focusable="False"
                          Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
                          Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
                          Command="{Binding Path=LayoutItem.HideCommand, RelativeSource={RelativeSource TemplatedParent}}"
                          ToolTip="{x:Static avalonDockProperties:Resources.Anchorable_BtnClose_Hint}">
                    <Border Background="White">
                      <Image Source="/Xceed.Wpf.AvalonDock;component/Themes/Generic/Images/PinClose.png">
                      </Image>
                    </Border>
                  </Button>
    
    
                </Grid>
              </Border>
              <ControlTemplate.Triggers>
                <DataTrigger Binding="{Binding Model.IsAutoHidden, RelativeSource={RelativeSource Mode=Self}}"
                             Value="True">
                  <Setter Property="LayoutTransform"
                          TargetName="PART_AutoHidePin">
                    <Setter.Value>
                      <RotateTransform Angle="90" />
                    </Setter.Value>
                  </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding Model.CanClose, RelativeSource={RelativeSource Mode=Self}}"
                             Value="True">
                  <Setter Property="Command"
                          TargetName="PART_HidePin"
                          Value="{Binding Path=LayoutItem.CloseCommand, RelativeSource={RelativeSource TemplatedParent}}" />
                  <Setter Property="ToolTip"
                          TargetName="PART_HidePin"
                          Value="{x:Static avalonDockProperties:Resources.Document_Close}" />
    
                </DataTrigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>