WPF, XAML: Как стиль ListBoxItem с использованием привязки к свойству объекта ListBox ItemsSource?
У меня есть ListBox, который связан с ObservableCollection из LogMessages.
public ObservableCollection<LogMessage> LogMessages { get; set; }
public LogMessageData()
{
this.LogMessages = new ObservableCollection<LogMessage>();
}
Каждое сообщение имеет два параметра:
public class LogMessage
{
public string Msg { get; set; }
public int Severity { get; set; }
//code cut...
}
ListBox заполняется этими элементами, и мне нужно цветной код (изменить цвет фона списка ListBoxItem) в зависимости от a Уровень важности элемента LogMessage.
Вот что у меня теперь в XAML пользовательского элемента управления, показывающего журнал:
<UserControl.Resources>
<AlternationConverter x:Key="BackgroundSeverityConverter">
<SolidColorBrush>Green</SolidColorBrush>
<SolidColorBrush>Yellow</SolidColorBrush>
<SolidColorBrush>Red</SolidColorBrush>
</AlternationConverter>
<Style x:Key="BindingAlternation" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Severity,
Converter={StaticResource BackgroundSeverityConverter}}"/>
</Style>
<DataTemplate x:Key="LogDataTemplate">
<TextBlock x:Name="logItemTextBlock" Width="Auto" Height="Auto"
Text="{Binding Msg}"/>
</DataTemplate>
</UserControl.Resources>
и фактический ListBox:
<ListBox IsSynchronizedWithCurrentItem="True"
ItemTemplate="{DynamicResource LogDataTemplate}"
ItemsSource="{Binding LogFacility.LogMessages}"
x:Name="logListBox" Grid.Row="1"
ItemContainerStyle="{StaticResource BindingAlternation}" />
AlternationConverter используется, потому что параметр серьезности сообщения имеет тип Int (0..3), и мы можем легко переключаться между стилями с помощью этого.
Концепция понятна, но пока это не работает для меня. Цвет фона в ListBoxItem не изменился.
Ответы
Ответ 1
Используйте ItemContainerStyle
:
<ListBox ItemsSource="{Binding LogMessages}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="{Binding Severity, Converter={StaticResource YourBackgroundConverter}}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Ответ 2
Как сказал Bojan, это RelativeSource, который не должен быть там.
Используйте {Binding Path = Severity, Converter = {StaticResource BackgroundSeverityConverter}}, когда вы привязываетесь к вашему объекту данных. RelativeSource.TemplatedParent предназначен для привязки к ListBoxItem.
Кроме того, что-то вроде домашнего животного, вы можете рассмотреть использование триггеров, например:
<Style x:Key="BindingAlternation" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Severity}" Value="1">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding Severity}" Value="2">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
<!-- etc.. -->
</Style.Triggers>
<Style x:Key="BindingAlternation" TargetType="{x:Type ListBoxItem}">
Но это только личное предпочтение.... то, что у вас там, должно хорошо работать, если вы исправляете привязку.