Listbox item WPF, different background color for different items

14,386

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..
}
Share:
14,386
mmvsbg
Author by

mmvsbg

SOreadytohelp

Updated on August 10, 2022

Comments

  • mmvsbg
    mmvsbg over 1 year

    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.

  • Sheridan
    Sheridan over 10 years
    +1 Now there's a proper answer... a little light on explanation (for users that require that), but a proper answer all the same.
  • Federico Berasategui
    Federico Berasategui over 10 years
    @Sheridan are you sure this will achieve what the OP is asking? check my answer
  • Sheridan
    Sheridan over 10 years
    +0 You're completely correct @HighCore... thanks, I need to pay more attention when I'm on this site. Not only would this not work at all, but even if it did work as eran planned, it would only work on the selected item.
  • Sheridan
    Sheridan over 10 years
    You might as well have eran's old +1 then. ;)
  • mmvsbg
    mmvsbg over 10 years
    That was very helpful, works like a charm. Thank you very much!
  • eran otzap
    eran otzap over 10 years
    @Sheridan It would work for the entire listbox , according the selected item
  • Sheridan
    Sheridan over 10 years
    @eranotzap, I tried it in Visual Studio... it didn't work. Even if it did, it wasn't what the question author asked for. Hopefully my comments have not upset or annoyed you. Maybe I could be more polite, but I just say things as I see them.