1

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>
thatguy
  • 21,059
  • 6
  • 30
  • 40
Yonnr
  • 81
  • 8

1 Answers1

2

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>
thatguy
  • 21,059
  • 6
  • 30
  • 40
  • A word of warning when styles are automatically applied to elements: WPF automatically adds elements into the visual tree. The styles are applied for these automatically created elements, too. I regularly got unexpected behaviour until I gave up this way – Klamsi Sep 23 '20 at 06:59
  • I prefer to set a x:Key to every style and assign it manually as a StaticResource to every element as shown above. – Klamsi Sep 23 '20 at 08:34
  • @Klamsi This is not true. The XAML parser does not add elements to the visual tree in order to be able to apply the `Style`. Why would this be necessary? If the `Style` itself does not add elements, then your statement is wrong. By default the `x:Key` of a `style` is set to the `Style.TargetType`, which actually makes it implicit. – BionicCode Sep 23 '20 at 08:42
  • @Klamsi The `FrameworkElement.Style` is actually resolved via the dependency property system using value precedence. If `FrameworkElement.Style` is not set i.e,`null`, the property system will start a lookup procedure to find a value. First step (before looking up theme dictionaries) is to try to find an implicit style for the current object type. – BionicCode Sep 23 '20 at 08:56
  • @Yonnr You are "safe" to use implicit styles or implicit resources in general. Resources don't modify your element tree just because they are implicit. – BionicCode Sep 23 '20 at 08:58