I am trying to change the background color of the selected items in a list box. I did that before by using
<SolidColorBrush x:Key="{x:Static SystemCo开发者_如何学Golors.ControlBrushKey}" Color="Yellow" />
which worked. But if I set IsEnabled to false on the ListBox, the whole background of the ListBox turns to the specified color of the ControlBrush. I only want to have the color changed if a ListBoxItem is selected and the ListBox has no focus.
I tried some varieties with triggers, but I can't get it to work. Even a multitrigger containing conditions with IsSelected and IsFocused didn't work for me.
Does anyone have a solution for me?
Edit: Tried the example with the ItemContainerStyle where I am getting a NullReferenceException in my project. In a new solution it works. That's the code where it doesn't work:
<ItemsControl ItemsSource="{Binding Path=Classification.Values}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsEnabled="{Binding Path=ClassificationEnabled}"
VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Grid.Row="0" x:Name="measureClassificationControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Category}"/>
<ListBox ItemsSource="{Binding Values.SortedList}" SelectionMode="Extended" Grid.Row="1" AlternationCount="2"
SelectionChanged="ListBox_SelectionChanged" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Height="120">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock TextWrapping="NoWrap" Text="{Binding Key}">
<TextBlock.ToolTip>
<ToolTip>
<TextBlock TextWrapping="NoWrap" Text="{Binding Value}"/>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Add the SystemColors.ControlBrushKey
to the ItemContainerStyle
instead. This way it will only affect the selected items.
Edit: Here is a complete Xaml example.
<StackPanel>
<ListBox IsEnabled="{Binding ElementName=enabledButton, Path=IsChecked}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Yellow" />
</Style.Resources>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem>Item 1</ListBoxItem>
<ListBoxItem>Item 2</ListBoxItem>
<ListBoxItem>Item 3</ListBoxItem>
<ListBoxItem>Item 4</ListBoxItem>
<ListBoxItem>Item 5</ListBoxItem>
</ListBox>
<ToggleButton Name="enabledButton" IsChecked="True" Content="IsEnabled"/>
</StackPanel>
You cannot have both
IsSelected
True
andIsEnabled
False
. AlsoIsFocused
True
andIsEnabled
False
.Your question talks about background color change for
IsSelected
asTrue
andIsFocused
as False.
In the code below (just paste ListBox
XAML in youre Window code)... all these state combinations are achieved ... to check if something is focused but not selected, you would have to select some row and then use "Control + Up / Down Arrow keys" to loose focus from the selected row and focus other non-selected rows.
You will also observe that the Orange
color for selected row's background would not appear (the Foreground
color Cyan
works though). For that background color change you must have to override the template of ListBoxItem.
<Window x:Class="WpfApplicationThemeTest.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Microsoft.Sample.Controls"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Window1">
<ListBox>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<!--Condition Property="IsEnabled" Value="False"/-->
<Condition Property="IsFocused" Value="True"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="Yellow"/>
</MultiTrigger>
<DataTrigger Binding="{Binding}" Value="My Value6">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsSource>
<x:Array Type="{x:Type sys:String}">
<sys:String>My Value1</sys:String>
<sys:String>My Value2</sys:String>
<sys:String>My Value3</sys:String>
<sys:String>My Value4</sys:String>
<sys:String>My Value5</sys:String>
<sys:String>My Value6</sys:String>
<sys:String>My Value7</sys:String>
<sys:String>My Value8</sys:String>
</x:Array>
</ListBox.ItemsSource>
</ListBox>
</Window>
I hope this guides you in correct direction.
Resolved the problem now. Problem seemed to be that the XamlParser doesn't like it when the system color is overwritten multiple times. So I defined it like that:
<Window x:Class="DataGridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit" xmlns:DataGridTest="clr-namespace:DataGridTest"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<DataGridTest:VM />
</Window.DataContext>
<StackPanel>
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.Resources>
<Style TargetType="ListBoxItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Yellow" />
</Style.Resources>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ListBox IsEnabled="{Binding ElementName=enabledButton, Path=IsChecked}">
<ListBoxItem>Item 1</ListBoxItem>
<ListBoxItem>Item 2</ListBoxItem>
<ListBoxItem>Item 3</ListBoxItem>
<ListBoxItem>Item 4</ListBoxItem>
<ListBoxItem>Item 5</ListBoxItem>
</ListBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ToggleButton Name="enabledButton" IsChecked="True" Content="IsEnabled"/>
</StackPanel>
</Window>
Thanks for your help!
精彩评论