Search code examples
wpfheaderstylesoverlapexpander

WPF expander style where the header overlaps content


I would like a WPF expander control where the header overlaps the main content area.

With the following XAML

<Expander Header="Details" ExpandDirection="Left">
    <Grid Background="Blue">
        <TextBlock Text="Details content" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5" Foreground="White"></TextBlock>
    </Grid>
</Expander>
<ScrollViewer Background="Red" HorizontalScrollBarVisibility="Visible" Grid.Column="1">
    <Grid Background="Red">
        <TextBlock Text="Main content"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
    </Grid>
</ScrollViewer>

I end up with:

Img1 enter image description here

I want to remove the white area and have the arrow in the top left corner of content area, overlap the red background. maps.bing.com is a similar example of this.


Solution

  • UPDATE:

    Found one solution that works for me. Maybe it can be of help to someone else searching for something similar.

    <UserControl x:Class="Expander_test2.Overlap"
                 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" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
    
        <UserControl.Resources>
    
            <Style x:Key="ExpanderLeftHeaderStyle"
                TargetType="{x:Type ToggleButton}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ToggleButton}">
                            <Border Padding="{TemplateBinding Padding}">
                                <Grid Background="Transparent"
                                    SnapsToDevicePixels="False">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="19"/>
                                        <RowDefinition Height="*"/>
                                    </Grid.RowDefinitions>
                                    <Path x:Name="arrow"
                                            HorizontalAlignment="Center"
                                            VerticalAlignment="Center"
                                            Stroke="{TemplateBinding Foreground}"
                                            StrokeThickness="1.5"
                                            SnapsToDevicePixels="false"
                                            Data="M 1,1.5 L 4.5,5 L 8,1.5">
                                        <Path.LayoutTransform>
                                            <RotateTransform Angle="90"/>
                                        </Path.LayoutTransform>
                                    </Path>
                                    <ContentPresenter Grid.Row="1"
                                                    Margin="0,4,0,0"
                                                    HorizontalAlignment="Center"
                                                    VerticalAlignment="Top"
                                                    SnapsToDevicePixels="True"
                                                    RecognizesAccessKey="True"/>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsChecked"
                                        Value="true">
                                    <Setter Property="Data"
                                        Value="M 1,4.5  L 4.5,1  L 8,4.5"
                                        TargetName="arrow"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    
            <Style x:Key="{x:Type Expander}"
                TargetType="{x:Type Expander}">
                <Setter Property="Foreground"
                    Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
                <Setter Property="Background"
                    Value="Transparent"/>
                <Setter Property="HorizontalContentAlignment"
                    Value="Stretch"/>
                <Setter Property="VerticalContentAlignment"
                    Value="Stretch"/>
                <Setter Property="BorderBrush"
                    Value="Transparent"/>
                <Setter Property="BorderThickness"
                    Value="1"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Expander}">
                            <Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                CornerRadius="3"
                                SnapsToDevicePixels="true">
                                <DockPanel>
                                    <Canvas>
                                        <ToggleButton x:Name="HeaderSite"
                                                Margin="1"
                                                MinWidth="0"
                                                MinHeight="0"
                                                Style="{StaticResource ExpanderLeftHeaderStyle}"
                                                IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                                Content="{TemplateBinding Header}"
                                                ContentTemplate="{TemplateBinding HeaderTemplate}"
                                                ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
                                                Foreground="{TemplateBinding Foreground}"
                                                Padding="{TemplateBinding Padding}"
                                                FontFamily="{TemplateBinding FontFamily}"
                                                FontSize="{TemplateBinding FontSize}"
                                                FontStyle="{TemplateBinding FontStyle}"
                                                FontStretch="{TemplateBinding FontStretch}"
                                                FontWeight="{TemplateBinding FontWeight}"
                                                HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    </Canvas>
                                    <ContentPresenter x:Name="ExpandSite"
                                                    DockPanel.Dock="Bottom"
                                                    Visibility="Collapsed"
                                                    Focusable="false"
                                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                    Margin="{TemplateBinding Padding}">
    
                                    </ContentPresenter>
                                </DockPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsExpanded"
                                        Value="true">
                                    <Setter Property="Visibility"
                                        Value="Visible"
                                        TargetName="ExpandSite"/>
                                    <Setter Property="Canvas.Left"
                                            Value="{Binding ActualWidth, ElementName=ExpandSite}"
                                            TargetName="HeaderSite" />
                                </Trigger>
                                <Trigger Property="ExpandDirection"
                                        Value="Left">
                                    <Setter Property="DockPanel.Dock"
                                        Value="Left"
                                        TargetName="ExpandSite"/>
                                    <Setter Property="DockPanel.Dock"
                                        Value="Right"
                                        TargetName="HeaderSite"/>
                                    <Setter Property="Style"
                                        Value="{StaticResource ExpanderLeftHeaderStyle}"
                                        TargetName="HeaderSite"/>
                                </Trigger>
                                <Trigger Property="IsEnabled"
                                        Value="false">
                                    <Setter Property="Foreground"
                                        Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </UserControl.Resources>
    
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
    
    
            <Expander Canvas.ZIndex="1" Header="Details" ExpandDirection="Left">
                <Grid Background="Blue">
                    <TextBlock Text="Details content" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5" Foreground="White"></TextBlock>
                </Grid>
            </Expander>
            <ScrollViewer Background="Red" HorizontalScrollBarVisibility="Visible" Grid.Column="1">
                <Grid Background="Red">
                    <TextBlock Text="Main content"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
                </Grid>
            </ScrollViewer>
    
        </Grid>
    
    </UserControl>
    

    Note: Canvas around the ToggleButton Canvas.ZIndex="1" for Expander Setter Property="Canvas.Left" in trigger for IsExpanded

    Result:

    enter image description here