Listbox item WPF, different background color for d

2019-02-16 16:59发布

问题:

I have a WPF ListBox containing a binded list of items from a specific class that I have. Something like this:

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

And the 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>

All works fine. What I want to do now is have a different background for each item in the ListBox depending on a certain property of the class. For example, let's say that the MyTable class has a property called isOccupied. If this flag is set for a certain item, I want it to have a red background in the ListBox, if it's not, then I want to have it with a green background. If the property changes, then the background should change accordingly.

Any tips on how to achieve this? I'm looking up some information regarding ItemContainerStyle at the moment but I'm relatively new to this so I'm not sure if I'm following the right path.

回答1:

You can achieve that using DataTriggers

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

Keep in mind that if you expect these values to change at runtime, your data item must properly implement and raise Property Change Notifications:

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


回答2:

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