I took the ListBox
of Expander
s path, and I am pretty pleased with the results.
Here's how my final code ended up:
Control Template for Expander Button
<ControlTemplate x:Key="TreeViewToggleButton" TargetType="{x:Type ToggleButton}">
<Border x:Name="ToggleButtonBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<Grid>
<Rectangle Fill="Transparent"/>
<Path x:Name="Arrow"
Height="10" Width="10"
Stroke="Black"
Data="m 2 1 v 8 l 4 -3.75 Z">
</Path>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Arrow" Property="Data" Value="m 2 9 h 5 v -5 Z"/>
<Setter TargetName="Arrow" Property="Fill" Value="Black"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Arrow" Property="Stroke" Value="#00A7C2"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="Arrow" Property="Fill" Value="#00A7C2"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Control Template for Expander
<ControlTemplate x:Key="TreeViewExpander" TargetType="{x:Type Expander}">
<DockPanel>
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ToggleButton x:Name="ExpanderButton"
Grid.Column="0"
Template="{StaticResource TreeViewToggleButton}"
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
Padding="2, 0" />
<Label Grid.Column="1" Content="{TemplateBinding Header}"
Padding="0, 1"/>
</Grid>
<ContentPresenter x:Name="ExpanderContent"
Visibility="Collapsed"
DockPanel.Dock="Bottom"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ExpanderContent" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Usage in Window
<ListBox Grid.Row="1" DataContext="{Binding Inputs}" ItemsSource="{Binding}" ScrollViewer.CanContentScroll="False">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Expander Template="{StaticResource TreeViewExpander}"
IsExpanded="{Binding IsExpanded}">
<Expander.Header>
<TextBlock Text="{Binding Timestamp, StringFormat=Time: {0}}"/>
</Expander.Header>
<ItemsControl ItemsSource="{Binding Variables}" Margin="30 0 0 0"/>
</Expander>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>