I've found a (somewhat hacky) but lightweight solution to this problem. I see that this question is pretty old, but nonetheless, I'll post the solution here for others to find.
In my TreeView, I override the two brushes used for setting the background of the TreeViewItem when its selection changes. I also create copies of the brushes so I can restore them later in my data template:
<TreeView ItemsSource="{Binding Path=SomeDataSource}">
<TreeView.Resources>
<SolidColorBrush x:Key="_CustomHighlightBrushKey" Color="{Binding Source={StaticResource {x:Static SystemColors.HighlightBrushKey}}, Path=Color}" />
<SolidColorBrush x:Key="_CustomControlBrushKey" Color="{Binding Source={StaticResource {x:Static SystemColors.ControlBrushKey}}, Path=Color}" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</TreeView.Resources>
</TreeView>
Note that I couldn't get this to work with a DynamicResource binding, so this solution probably won't work with theme changes. I would be very interested to know if there is a way to do this.
I then use the following hierarchical data template for formatting tree nodes:
<HierarchicalDataTemplate DataType="{x:Type SomeViewModelType}" ItemsSource="{Binding Path=Children}">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding Source={StaticResource {x:Static SystemColors.HighlightBrushKey}}, Path=Color}" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{Binding Source={StaticResource {x:Static SystemColors.ControlBrushKey}}, Path=Color}" />
</StackPanel.Resources>
<Image SnapsToDevicePixels="True" Source="...">
</Image>
<TextBlock Text="{Binding Path=DisplayName}" Margin="5,0">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True">
<Setter Property="Background" Value="{DynamicResource _CustomHighlightBrushKey}" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True" />
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelectionActive}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{DynamicResource _CustomControlBrushKey}" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Resources>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
Note that I restore the system brushes to their original (static) values so context menus can be rendered correctly.