WPF Docking Document Tab Icon

by Weifen Luo (DevZest) 25. August 2009 09:52

Untitled Untitled2

A commonly required feature for WPF Docking is the ability to show/hide icon for document tab. Though it can be accomplished by apply a custom template for DocumentTab class, we added this feature in version 1.0.3520 to make everybody’s life easier.

A new DocumentTab.ShowsIcon attached property determines whether the icon should be displayed for document tab. Note this is a attached property getting/setting to DockControl, which means it takes effect for all document tabs in the DockControl. We made this design decision to separate the implementation to DocumentTab class, keeping the whole library loosely coupled.

The following XAML code demonstrates the use of this new feature:

xmlns:dz="http://schemas.devzest.com/presentation/docking"
...
<dz:DockControl dz:DocumentTab.ShowsIcon="True" ...>
...
</dz:DockControl>

The default template for DocumentTab is also changed as the following:

<Style TargetType="primitives:DocumentTab">
    <Setter Property="ToolTip" Value="{Binding Description}" />
    <Setter Property="primitives:DockManager.TargetItem" Value="{Binding}" />
    <Setter Property="primitives:DockManager.TargetPosition" Value="Tab" />
    <Setter Property="Margin" Value="-5,0,-5,0" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="primitives:DocumentTab" >
                <ControlTemplate.Resources>
                    <SolidColorBrush x:Key="BrushBorder" Color="#FFB4B4B4" />

                    <LinearGradientBrush x:Key="BrushUnselected" StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Color="#FFD7E4F2" Offset="0" />
                        <GradientStop Color="#FFB9D1EA" Offset="1" />
                    </LinearGradientBrush>

                    <LinearGradientBrush x:Key="BrushSelected" StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Color="#FFFFFFFF" Offset="0" />
                        <GradientStop Color="#FFD7E4F2" Offset="1" />
                    </LinearGradientBrush>

                    <LinearGradientBrush x:Key="BrushMouseOver" StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Color="#FFFFFFFF" Offset="0" />
                        <GradientStop Color="#FF3399FF" Offset="1" />
                    </LinearGradientBrush>

                    <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="VerticalAlignment" Value="Center" />
                        <Setter Property="Text" Value="{Binding TabText}" />
                        <Setter Property="TextWrapping" Value="NoWrap" />
                        <Setter Property="TextTrimming" Value="CharacterEllipsis" />
                    </Style>
                </ControlTemplate.Resources>
                <Border x:Name="outmostBorder" BorderThickness="0" SnapsToDevicePixels="True"
                        BorderBrush="{StaticResource _BrushDocumentWindowBorderBody}"
                        ContextMenu="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.TabContextMenu}">
                    <Grid x:Name="grid">
                        <primitives:DocumentTabChrome x:Name="innerChrome" SnapsToDevicePixels="True" Margin="1,1,1,0"
                            BorderBrush="{StaticResource _BrushDocumentWindowInnerBorder}"
                            Background="{StaticResource BrushUnselected}" />
                        <primitives:DocumentTabChrome x:Name="outerChrome" SnapsToDevicePixels="True"
                            BorderBrush="{StaticResource BrushBorder}" />
                        <Grid Margin="17,1,4,0" VerticalAlignment="Center">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Image Visibility="Collapsed" x:Name="iconImage" Margin="0,0,3,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0" Source="{Binding Path=Icon}" Stretch="None" />
                            <TextBlock Grid.Column="1" x:Name="inactiveTabTextBlock" Style="{StaticResource TextBlockStyle}" />
                            <TextBlock Grid.Column="1" x:Name="activeTabTextBlock" Style="{StaticResource TextBlockStyle}"
                                   FontWeight="UltraBold" Height="0" Visibility="Hidden" />
                        </Grid>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="UIElement.IsMouseOver" Value="True">
                        <Setter TargetName="innerChrome" Property="Background" Value="{StaticResource BrushMouseOver}" />
                    </Trigger>
                    <DataTrigger Binding="{Binding Path=DockControl.(primitives:DocumentTab.ShowsIcon)}" Value="True">
                        <Setter TargetName="iconImage" Property="Visibility" Value="Visible" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
                        <Setter Property="Panel.ZIndex" Value="1" />
                        <Setter TargetName="outmostBorder" Property="BorderThickness" Value="0,0,0,2.5" />
                        <Setter TargetName="outmostBorder" Property="Margin" Value="0,-2,0,-2" />
                        <Setter TargetName="outerChrome" Property="BorderBrush" Value="{StaticResource _BrushDocumentWindowBorder}" />
                        <Setter TargetName="innerChrome" Property="Background" Value="{StaticResource BrushSelected}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=IsActiveDocument}" Value="True">
                        <Setter TargetName="activeTabTextBlock" Property="Visibility" Value="Visible" />
                        <Setter TargetName="activeTabTextBlock" Property="Height" Value="Auto" />
                        <Setter TargetName="inactiveTabTextBlock" Property="Visibility" Value="Hidden" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=(primitives:DockManager.Preview)}" Value="Tab">
                        <Setter TargetName="grid" Property="primitives:DockManager.Adorner">
                            <Setter.Value>
                                <DataTemplate>
                                    <Decorator DataContext="{Binding DataContext}" Margin="0,0,0,-1">
                                        <primitives:DocumentTabChrome DataContext="{Binding DockControl}"
                                            Opacity="{Binding Path=(primitives:DockManager.PreviewOpacity)}"
                                            Background="{Binding Path=(primitives:DockManager.PreviewBrush)}" />
                                    </Decorator>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Note the data trigger binding to DockControl.(primitives:DocumentTab.ShowsIcon). This is a clean implementation limits to DocumentTab class only.

Tags: ,

WPF

Comments are closed

Copyright DevZest, 2008 - 2017