Search code examples
wpfxamlbordercontroltemplategroupbox

Is it possible to display the header of a GroupBox above the Border?


Is it possible to display the header of a GroupBox above the border and not in the border?

<GroupBox>
 <GroupBox.Header>
  <TextBlock 
   Text="Test">    
  </TextBlock>
 </GroupBox.Header>
</GroupBox>

Solution

  • You have to edit the control template of the GroupBox and adapt it. You can extract the default control template using Visual Studio or Blend. It contains an opacity mask that creates the gap for the header text in the border of the group box. You have to remove this border and move the header like this:

    <Style x:Key="GroupBoxStyle" TargetType="{x:Type GroupBox}">
       <Setter Property="BorderBrush" Value="#D5DFE5"/>
       <Setter Property="BorderThickness" Value="1"/>
       <Setter Property="Template">
          <Setter.Value>
             <ControlTemplate TargetType="{x:Type GroupBox}">
                <Grid SnapsToDevicePixels="true">
                   <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="6"/>
                      <ColumnDefinition Width="Auto"/>
                      <ColumnDefinition Width="*"/>
                      <ColumnDefinition Width="6"/>
                   </Grid.ColumnDefinitions>
                   <Grid.RowDefinitions>
                      <RowDefinition Height="Auto"/>
                      <RowDefinition Height="Auto"/>
                      <RowDefinition Height="*"/>
                      <RowDefinition Height="6"/>
                   </Grid.RowDefinitions>
                   <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Transparent" CornerRadius="4" Grid.ColumnSpan="4" Grid.Column="0" Grid.RowSpan="3" Grid.Row="1"/>
                   <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="White" CornerRadius="4" Grid.ColumnSpan="4" Grid.RowSpan="3" Grid.Row="1">
                      <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3">
                         <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="White" CornerRadius="2"/>
                      </Border>
                   </Border>
                   <Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.Row="0">
                      <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                   </Border>
                   <ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
             </ControlTemplate>
          </Setter.Value>
       </Setter>
    </Style>
    

    Then you can use the style in your XAML explictly like this to apply the control template:

    <GroupBox Style="{StaticResource GroupBoxStyle}" Header="Test">
       <!-- ...your content. -->
    </GroupBox>
    

    Alternatively define the group box style as implicit style to automatically apply it on all GroupBoxes.

    <Style TargetType="{x:Type GroupBox}">
       <!-- ...same as above. -->
    </Style>