I made a custom control template that turns a groupbox into an expander (clicking on the header expands/collapses the content of the groupbox). It works fine except that mouse clicks don't always go through: sometimes it doesn't expand/collapse when you click on the header, esp. when you click inside the "o"s in the word "Colors". I organically thought it was caused by the text in the header trapping mouse clicks which prevent them from going through so I played around with the IsHitTestVisible and IsFocusable properties on the content header, etc., which doesn't seem to have any effect. A header that only contains empty strings or even no content seems to have the same issue.
The XAML is posted below.
(BTW, this post which turns an expander into a groupbox seems to have similar issue: If you click right inside the arrow, the togglebutton won't toggle.)
<Window x:Class="TestCollapsibleGroupBoxStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="boolToVizConverter"/>
<Color x:Key="HyperlinkHoverBlue">#FF0088CC</Color>
<SolidColorBrush x:Key="HyperlinkHoverBlueBrush" Color="{StaticResource HyperlinkHoverBlue}" />
<PathGeometry x:Key="TreeArrow">
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsFilled="True"
StartPoint="0 0"
IsClosed="True">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="0 6"/>
<LineSegment Point="6 0"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style x:Key="CollapsibleGroupBoxStyle" TargetType="{x:Type GroupBox}" BasedOn="{StaticResource {x:Type GroupBox}}">
<Style.Resources>
<Style x:Key="ToggleHeaderStyle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="MinWidth" Value="72"/>
<Setter Property="Padding" Value="2,1"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Background="Transparent" MinHeight="30"
Padding="{TemplateBinding Padding}" Focusable="False">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Focusable="False"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Path x:Name="ExpandPath"
VerticalAlignment="Center"
Margin="4,2,0,0"
HorizontalAlignment="Right"
Fill="Transparent"
Stroke="#FF989898"
Data="{StaticResource TreeArrow}">
<Path.RenderTransform>
<RotateTransform Angle="135"
CenterX="3"
CenterY="3"/>
</Path.RenderTransform>
</Path>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.Setters>
<Setter Property="Foreground" Value="{StaticResource HyperlinkHoverBlueBrush}"/>
<Setter TargetName="ExpandPath" Property="Stroke" Value="#FF1BBBFA"/>
<Setter TargetName="ExpandPath" Property="Fill" Value="Transparent"/>
</Trigger.Setters>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ExpandPath" Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="180"
CenterX="3"
CenterY="3"/>
</Setter.Value>
</Setter>
<Setter TargetName="ExpandPath" Property="Fill" Value="#FF595959"/>
<Setter TargetName="ExpandPath" Property="Stroke" Value="#FF262626"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush"
Value="Gray"/>
<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 CornerRadius="4"
Grid.Row="1"
Grid.RowSpan="3"
Grid.Column="0"
Grid.ColumnSpan="4"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Transparent"
Background="{TemplateBinding Background}"/>
<Border x:Name="Header"
Padding="3,1,3,0"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1">
<ToggleButton x:Name="headerToggleBtn"
Content="{TemplateBinding Header}"
Style="{StaticResource ToggleHeaderStyle}">
</ToggleButton>
</Border>
<ContentPresenter x:Name="ContentSite" Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Border CornerRadius="4"
Grid.Row="1"
Grid.RowSpan="3"
Grid.ColumnSpan="4"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="White">
<Border.OpacityMask>
<MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
ConverterParameter="7">
<Binding ElementName="Header"
Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="ActualHeight"/>
</MultiBinding>
</Border.OpacityMask>
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="3">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="White"
CornerRadius="2"/>
</Border>
</Border>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName=headerToggleBtn, Path=IsChecked}" Value="False">
<Setter Property="Visibility" TargetName="ContentSite" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal">
<GroupBox Header="Colors" Style="{StaticResource CollapsibleGroupBoxStyle}">
<StackPanel Orientation="Vertical">
<RadioButton GroupName="colorGrp" Content="Red"/>
<RadioButton GroupName="colorGrp" Content="Blue"/>
<RadioButton GroupName="colorGrp" Content="Red"/>
</StackPanel>
</GroupBox>
<GroupBox>
<GroupBox.Header>
<ToggleButton Name="ToggleHeader">
<TextBlock Text="Colors" FontSize="18"/>
</ToggleButton>
</GroupBox.Header>
<StackPanel Orientation="Vertical" Visibility="{Binding ElementName=ToggleHeader, Path=IsChecked, Mode=TwoWay, Converter={StaticResource boolToVizConverter}}">
<RadioButton GroupName="colorGrp" Content="Red"/>
<RadioButton GroupName="colorGrp" Content="Blue"/>
<RadioButton GroupName="colorGrp" Content="Red"/>
</StackPanel>
</GroupBox>
<GroupBox Header=" " Style="{StaticResource CollapsibleGroupBoxStyle}">
<StackPanel Orientation="Vertical">
<RadioButton GroupName="colorGrp" Content="Red"/>
<RadioButton GroupName="colorGrp" Content="Blue"/>
<RadioButton GroupName="colorGrp" Content="Red"/>
</StackPanel>
</GroupBox>
</StackPanel>
</Window>
Set
IsHitTestVisible
of your groupbox's border toFalse
: