Alternate Background for ListViewItems

This sample shows how to create a ListView control that uses a GridView to display a list of dates that are defined as DateTime objects. Items in this example have alternate background.

 

Key Step 1. Restyle ListViewItem, and set its Background by converter in the new style.

 

    <l:BackgroundConvertor x:Key="myConverter"/>

    <Style x:Key="myItemStyle" TargetType="{x:Type ListViewItem}">

      <Setter Property="Background">

        <Setter.Value>

          <Binding RelativeSource="{RelativeSource Self}" Converter="{StaticResource myConverter}"/>

        </Setter.Value>

      </Setter>

</Style>

<ListView Name="lv" ItemContainerStyle="{StaticResource myItemStyle}" />

Key Step 2 . Implement BackgroundConvertor. We need the index of a ListViewItem to determine its background. int ItemContainerGenerator.IndexFromContainer(DependencyObject container) method can tell the index of a ListViewItem.

 

public sealed class BackgroundConvertor : 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.White;

        }

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

    {

        throw new NotSupportedException();

    }

}

Key Step 3. We’ve almost finished the sample, and it works well in sorting/grouping. However, when one item is removed from the ListView, you may find two adjacent rows have the same background color. That's because the background of all the other items will not be updated automatically after removing/inserting. Therefore, some extra code is needed to refresh the items after the inserting/removing operation.

 

private void Remove(object sender, RoutedEventArgs e)

{

    _data.RemoveAt(3);

    // Must refresh all the items to update the background

    ICollectionView dataView =

      CollectionViewSource.GetDefaultView(lv.ItemsSource);

    dataView.Refresh();

}

This sample is based on the February CTP.

AlternateBackground.zip