How to: Alternate the Background Color for Rows in a ListView

This example shows three methods that you can use to alternate the Background color for rows in a ListView.

Example

The following sections provide three methods to create a ListView with rows that alternate in Background color. The example also discusses a method for updating the view when you add or remove rows.

Method 1: Define a Style That Uses an IValueConverter to Alternate Background Color

The following example shows how to define a Style for a ListViewItem control that binds the value of the Background property to an IValueConverter.

<Style x:Key="myItemStyle" TargetType="{x:Type ListViewItem}">
  <Setter Property="Background">
    <Setter.Value>
      <Binding RelativeSource="{RelativeSource Self}" 
               Converter="{StaticResource myConverter}"/>
    </Setter.Value>
  </Setter>
</Style>

The following example defines a ResourceKey for the IValueConverter.

<namespc:BackgroundConverter x:Key="myConverter"/>

The following example shows the definition of the IValueConverter that sets the Background property according to the row index.

    Public NotInheritable Class BackgroundConverter
        Implements IValueConverter
        Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.Convert
            Dim item As ListViewItem = CType(value, ListViewItem)
            Dim listView As ListView = TryCast(ItemsControl.ItemsControlFromItemContainer(item), ListView)
            ' Get the index of a ListViewItem
            Dim index As Integer = listView.ItemContainerGenerator.IndexFromContainer(item)

            If index Mod 2 = 0 Then
                Return Brushes.LightBlue
            Else
                Return Brushes.Beige
            End If
        End Function
public sealed class BackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        CultureInfo culture)
    {
        ListViewItem item = (ListViewItem)value;
        ListView listView = 
            ItemsControl.ItemsControlFromItemContainer(item) as ListView;
        // Get the index of a ListViewItem
        int index = 
            listView.ItemContainerGenerator.IndexFromContainer(item);

        if (index % 2 == 0)
        {
            return Brushes.LightBlue;
        }
        else
        {
            return Brushes.Beige;
        }
    }

The following example shows how to define a ListView that uses Style as its ItemContainerStyle in order to provide the required layout.

<ListView Name="theListView" 
          ItemsSource="{Binding Source={StaticResource EmployeeData}, 
                                        XPath=Employee}"
          ItemContainerStyle="{StaticResource myItemStyle}" >
  <ListView.View>
    <GridView>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=FirstName}" 
                      Header="First Name" Width="120"/>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=LastName}" 
                      Header="Last Name" Width="120"/>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=FavoriteCity}" 
                      Header="Favorite City" Width="120"/>
    </GridView>
  </ListView.View>
</ListView>

Method 2: Derive a New Class from ListView to Alternate Background Color

The following example shows how to define a class that derives from ListView. This class overrides the PrepareContainerForItemOverride method in order to create rows that have alternating Background colors.

    Public Class SubListView
        Inherits ListView
        Protected Overrides Sub PrepareContainerForItemOverride(ByVal element As DependencyObject, ByVal item As Object)
            MyBase.PrepareContainerForItemOverride(element, item)
            If TypeOf View Is GridView Then
                Dim index As Integer = ItemContainerGenerator.IndexFromContainer(element)
                Dim lvi As ListViewItem = TryCast(element, ListViewItem)
                If index Mod 2 = 0 Then
                    lvi.Background = Brushes.LightBlue
                Else
                    lvi.Background = Brushes.Beige
                End If
            End If
        End Sub
    End Class
public class SubListView : ListView
{
    protected override void
        PrepareContainerForItemOverride(DependencyObject element,
        object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        if (View is GridView)
        {
            int index = ItemContainerGenerator.IndexFromContainer(element);
            ListViewItem lvi = element as ListViewItem;
            if (index % 2 == 0)
            {
                lvi.Background = Brushes.LightBlue;
            }
            else
            {
                lvi.Background = Brushes.Beige;
            }
        }
    }
}

The following example shows how to create an instance of this class. The namespc prefix maps to a common language runtime (CLR) namespace and the corresponding assembly where the StyleSelector is defined.

<namespc:SubListView
      ItemsSource="{Binding Source={StaticResource EmployeeData}, 
                                        XPath=Employee}">
  <namespc:SubListView.View>
    <GridView>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=FirstName}" 
                      Header="First Name" Width="120"/>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=LastName}" 
                      Header="Last Name" Width="120"/>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=FavoriteCity}" 
                      Header="Favorite City" Width="120"/>
    </GridView>
  </namespc:SubListView.View>
</namespc:SubListView>

Method 3: Use a StyleSelector to Alternate Background Color

The following example shows how to define a StyleSelector that defines a Style for a row. This example defines the Background color according to the row index.

    Public Class ListViewItemStyleSelector
        Inherits StyleSelector
        Public Overrides Function SelectStyle(ByVal item As Object, ByVal container As DependencyObject) As Style
            Dim st As New Style()
            st.TargetType = GetType(ListViewItem)
            Dim backGroundSetter As New Setter()
            backGroundSetter.Property = ListViewItem.BackgroundProperty
            Dim listView As ListView = TryCast(ItemsControl.ItemsControlFromItemContainer(container), ListView)
            Dim index As Integer = listView.ItemContainerGenerator.IndexFromContainer(container)
            If index Mod 2 = 0 Then
                backGroundSetter.Value = Brushes.LightBlue
            Else
                backGroundSetter.Value = Brushes.Beige
            End If
            st.Setters.Add(backGroundSetter)
            Return st
        End Function
    End Class
public class ListViewItemStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, 
        DependencyObject container)
    {
        Style st = new Style();
        st.TargetType = typeof(ListViewItem);
        Setter backGroundSetter = new Setter();
        backGroundSetter.Property = ListViewItem.BackgroundProperty;
        ListView listView = 
            ItemsControl.ItemsControlFromItemContainer(container) 
              as ListView;
        int index = 
            listView.ItemContainerGenerator.IndexFromContainer(container);
        if (index % 2 == 0)
        {
            backGroundSetter.Value = Brushes.LightBlue;
        }
        else
        {
            backGroundSetter.Value = Brushes.Beige;
        }
        st.Setters.Add(backGroundSetter);
        return st;
    }
}    

The following example shows how to define a ResourceKey for the StyleSelector. The namespc prefix maps to a CLR namespace and the corresponding assembly where the StyleSelector is defined. For more information, see XAML Namespaces and Namespace Mapping for WPF XAML.

<namespc:ListViewItemStyleSelector x:Key="myStyleSelector"/>

The following example shows how to set the ItemContainerStyleSelector property of a ListView to this StyleSelector resource.

<ListView 
      ItemsSource="{Binding Source={StaticResource EmployeeData}, 
                                        XPath=Employee}"
      ItemContainerStyleSelector="{DynamicResource myStyleSelector}" >      
  <ListView.View>
    <GridView>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=FirstName}" 
                      Header="First Name" Width="120"/>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=LastName}" 
                      Header="Last Name" Width="120"/>
      <GridViewColumn DisplayMemberBinding="{Binding XPath=FavoriteCity}" 
                      Header="Favorite City" Width="120"/>
    </GridView>
  </ListView.View>
</ListView>

Update the ListView After a Change in the ListViewItem Collection

If you add or remove a ListViewItem from a ListView control, you must update the ListViewItem controls in order to recreate the alternating Background color. The following example shows how to update the ListViewItem controls.

          Dim dataView As ICollectionView = CollectionViewSource.GetDefaultView(theListView.ItemsSource)
          dataView.Refresh()
ICollectionView dataView =
  CollectionViewSource.GetDefaultView(theListView.ItemsSource);
dataView.Refresh();

See Also

Reference

GridView

ListView

Concepts

ListView Overview

GridView Overview

Other Resources

ListView How-to Topics