WPF中的Listbox项目:为不同项目设置不同的背景颜色

10

我有一个 WPF ListBox,其中包含来自特定类的绑定项目列表。类似于这样:

    ObservableCollection<MyTable> tables = new ObservableCollection<MyTable>();
...
    listTables.ItemsSource = tables;

并且 XAML:

<ListBox HorizontalAlignment="Left" Margin="8,10,0,0" Name="listTables" Width="153" ItemsSource="{Binding tables}" SelectionChanged="listTables_SelectionChanged" Height="501" VerticalAlignment="Top">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="1">
                    <TextBlock Grid.Column="1" Text="{Binding tableName}" />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

一切都很好。现在我想做的是,根据类的某个特定属性为ListBox中的每个项目设置不同的背景。例如,假设MyTable类具有名为isOccupied的属性。如果某个项目设置了该标志,则我希望在ListBox中它具有红色背景,如果没有,则希望它具有绿色背景。如果该属性更改,则背景应相应更改。

如何实现这一点?我目前正在查找有关ItemContainerStyle的信息,但我相对较新,所以不确定是否走上了正确的道路。

2个回答

16

您可以使用DataTrigger来实现。

<ListBox.ItemTemplate>
    <DataTemplate>

        <!-- Step #1: give an x:Name to this Grid -->
        <Grid Margin="1" x:Name="BackgroundGrid">
            <TextBlock Grid.Column="1" Text="{Binding tableName}" />
        </Grid>

        <!-- Step #2: create a DataTrigger that sets the Background of the Grid, depending on the value of IsOccupied property in the Model -->             
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsOccupied}" Value="True">
                <Setter TargetName="BackgroundGrid" Property="Background" Value="Red"/>
            </DataTrigger>

            <DataTrigger Binding="{Binding IsOccupied}" Value="False">
                <Setter TargetName="BackgroundGrid" Property="Background" Value="Green"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ListBox.ItemTemplate>

请记住,如果您希望这些值在运行时更改,那么您的数据项必须正确实现并触发属性更改通知

public class MyTable: INotifyPropertyChanged //Side comment: revise your naming conventions, this is not a table.
{
   private bool _isOccupied;
   public bool IsOccupied
   {
       get { return _isOccupied; }
       set
       {
           _isOccupied = value;
           NotifyPropertyChange("IsOccupied");
       }
    }

    //.. Other members here..
}

你最好拿到Eran的旧+1。 ;) - Sheridan
非常有用,顺利运作。非常感谢! - mmvsbg

0
<Style TargetType="ListBox" x:Key="myListBoxStyle">
    <Style.Triggers>
        <DataTrigger Binding="{Binding SelectedItem.IsOccupied}" Value="True">
            <Setter Property="Background" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>

现在有一个正确的答案了...对于那些需要解释的用户来说,解释有点少,但总体上是一个正确的答案。 - Sheridan
@Sheridan,你确定这样做能够实现OP所要求的吗?请检查我的答案。 - Federico Berasategui
你说得完全正确,@HighCore...谢谢,我需要更加注意当我在这个网站上的时候。不仅这根本行不通,即使它按照Eran计划的方式工作,它也只能在所选项目上工作。 - Sheridan
@Sheridan 根据所选项目,它将适用于整个列表框。 - eran otzap
@eranotzap,我在Visual Studio中尝试了一下...它没有起作用。即使它起作用了,也不是问题作者要求的。希望我的评论没有让你感到不安或烦恼。也许我可以更礼貌,但我只是按照自己的看法说话。 - Sheridan

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