WPF、XAML:如何使用 ListBox ItemsSource 对象的属性绑定来设置 ListBoxItem 的样式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1305157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:53:18  来源:igfitidea点击:

WPF, XAML: How to style a ListBoxItem using binding on property of ListBox ItemsSource object?

wpfxamlbindinglistboxstyling

提问by Igor Malin

I have a ListBox which is bound to ObservableCollection of LogMessages.

我有一个绑定到 LogMessages 的 ObservableCollection 的 ListBox。

public ObservableCollection<LogMessage> LogMessages { get; set; }
public LogMessageData()
{
    this.LogMessages = new ObservableCollection<LogMessage>();
}

Each Message has two parameters:

每个消息有两个参数:

public class LogMessage
{
    public string Msg { get; set; }
    public int Severity { get; set; }
    //code cut...
}

ListBox is getting filled with those Items, and I need to color-code(change a background colorof ListBoxItem) list depending on a Severityparameter of a LogMessage item.

列表框是越来越充满了这些项目,我需要的颜色代码(改变背景颜色一个ListBoxItem)列表取决于严重性一个的LogMessage项的参数。

Here's what I have now in XAML of user control showing the log:

这是我现在在用户控件的 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>

and an actual ListBox:

和一个实际的列表框:

<ListBox IsSynchronizedWithCurrentItem="True" 
    ItemTemplate="{DynamicResource LogDataTemplate}" 
    ItemsSource="{Binding LogFacility.LogMessages}" 
    x:Name="logListBox" Grid.Row="1" 
    ItemContainerStyle="{StaticResource BindingAlternation}" />

The AlternationConverter is used because the Severity parameter of message is of type Int (0..3), and we can easily switch between styles using that one.

使用 AlternationConverter 是因为消息的 Severity 参数是 Int (0..3) 类型,我们可以使用该参数轻松切换样式。

The concept is clear, but so far it does not work for me. The Background color of ListBoxItem did not change.

这个概念很清楚,但到目前为止它对我不起作用。ListBoxItem 的背景颜色没有改变。

回答by Kent Boogaart

Use ItemContainerStyle:

使用ItemContainerStyle

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

回答by Bubblewrap

Like Bojan commented, it's the RelativeSource which shouldnt be there. Use {Binding Path=Severity, Converter={StaticResource BackgroundSeverityConverter}}when you're binding to your data object. RelativeSource.TemplatedParent is for binding to ListBoxItem.

就像 Bojan 评论的那样,RelativeSource 不应该在那里。绑定到数据对象时请使用{Binding Path=Severity, Converter={StaticResource BackgroundSeverityConverter}}。RelativeSource.TemplatedParent 用于绑定到 ListBoxItem。

Additionally, something of a pet peeve of mine, you could consider using triggers, for example:

此外,我有点讨厌,您可以考虑使用触发器,例如:

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

But that's just a personal preference....what you have there should work fine if you fix the binding.

但这只是个人偏好......如果你修复绑定,你在那里应该可以正常工作。