Я нашел (несколько хакерское), но легкое решение этой проблемы. Я вижу, что этот вопрос довольно старый, но, тем не менее, я опубликую решение здесь, чтобы другие могли его найти.
В моем TreeView я перезаписываю две кисти, используемые для установки фона TreeViewItem, когда меняется его выбор. Я также создаю копии кистей, чтобы потом восстановить их в своем шаблоне данных:
<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>
Обратите внимание, что я не смог заставить это работать с привязкой DynamicResource, поэтому это решение, вероятно, не будет работать с изменениями темы. Мне было бы очень интересно узнать, есть ли способ сделать это.
Затем я использую следующий шаблон иерархических данных для форматирования узлов дерева:
<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>
Обратите внимание, что я возвращаю системным кистям их исходные (статические) значения, чтобы контекстные меню могли отображаться правильно.