WPF, XAML:如何使用绑定样式一个ListBoxItem,根据ListBox的ItemsSource对象的属性?

16

我有一个ListBox,它绑定了LogMessages的ObservableCollection。

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正在填充这些项,我需要根据LogMessage项目的Severity参数对列表进行颜色编码(更改 ListBoxItem的背景颜色 )。

这是我现在在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是因为消息的Severity参数是Int类型(0..3),通过使用该参数,我们可以轻松地在各种样式之间切换。

概念很清楚,但直到现在它对我没有用。 ListBoxItem的背景颜色没有改变。


我的直觉是这与{RelativeSource TemplatedParent}有关。调试应用程序时,输出窗口是否出现任何绑定错误? - Bojan Resnik
没有绑定错误,但不幸的是,你是正确的,这与我正在尝试引用的对象无关。奇怪的是输出窗口中没有绑定错误。 - Igor Malin
2个回答

30

使用ItemContainerStyle

<ListBox ItemsSource="{Binding LogMessages}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Background" Value="{Binding Severity, Converter={StaticResource YourBackgroundConverter}}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

4

像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}">

但那只是个人偏好……如果你修复绑定,你所拥有的应该可以正常工作。

我已经使用Kent的解决方案修复了问题,但我也会尝试你的解决方案。当然,在其他情况下它可能会很有用。使用AlternationConverter的目的是它可以轻松解释我们在LogMessage中拥有的整数数据。你的方法更加通用,因此它将适用于更多的情况。谢谢! - Igor Malin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接