According to this, overriding the ControlBrushKey resource should change the background color of a ListBox selected item when it doesn't have focus. I created a simple example to disprove this:
<StackPanel>
<ListBox>
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/>
<!--SelectedItem without focus but doesn't really work-->
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Orange" />
</ListBox.Resources>
<ListBoxItem>
Item 1
</ListBoxItem>
<ListBoxItem>
Item 2
</ListBoxItem>
</ListBox>
<TextBox></TextBox>
</StackPanel>
If you run this in .NET 4.5 you can see that it only changes the in-focus color, but not the not-in-focus (it works in .NET 4.0). Any idea why?
Edit: This seems to be duplicate of List/Combo Box Background And Selected Colours Under .net 4.5.
Try the following for changing the selected ListBoxItem's background color when it has lost focus:
XAML
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey }" Color="Orange" />
</ListBox.Resources>
C#
listBox.Resources.Add(SystemColors.InactiveSelectionHighlightBrushKey,
new SolidColorBrush(Colors.Orange));
I hope it works for you.
It's all about the default templates of the controls, if they do not use the system colors as they did in .NET 4 this will simply not change anything.
Here's what I came up with that doesn't involve changing system colors or control templates. Simply wrap the ListBox in a new UserControl.
public partial class StyledListBox : UserControl
{
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public StyledListBox()
{
InitializeComponent();
}
public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(StyledListBox), new FrameworkPropertyMetadata(null));
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(StyledListBox), new FrameworkPropertyMetadata(null));
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(StyledListBox), new FrameworkPropertyMetadata(null)
{
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
}
XAML:
<UserControl x:Class="StyledListBox"
<ListBox ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:StyledListBox}}}"
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:StyledListBox}}}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<ContentPresenter ContentTemplate="{Binding ItemTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StyledListBox}}}" />
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl>
Then simply use the wrapper UserControl as if it were a ListBox. Any other ListBox properties you want to control can simply be added to the wrapper in the same manner as ItemsSource
and SelectedItem
from my example.
The solution to this is adding
FrameworkCompatibilityPreferences.AreInactiveSelectionHighlightBrushKeysSupported = false;
before calling
InitializeComponent();