Q102. ListBox で一行おきに背景色を変えるには?

A.StyleSelector を使用します。

以下サンプルです。奇数行と偶数行で背景色を設定します。


まず StyleSelector を継承したクラスを作成し、奇数行・偶数行のスタイルを保持するようプロパティを設けます。そして SelectStyle メソッドをオーバーライドし、奇数行・偶数行ごとに返却するスタイルを入れ替えるようにします。現在のアイテムが奇数なのか偶数なのかを取得するには ItemsControl.ItemsControlFromItemContainer を使いますが、この辺りはどうも定番のテクニックのようです。

// C#
using System.Windows;
using System.Windows.Controls;

public class ListBoxStyleSelector : StyleSelector {
    /// <summary>偶数スタイルを取得・設定します。</summary>
    public Style EvenStyle { get; set; }

    /// <summary>奇数スタイルを取得・設定します。</summary>
    public Style OddStyle { get; set; }

    public override Style SelectStyle(object item, DependencyObject container) {
        var control = ItemsControl.ItemsControlFromItemContainer(container);
        if ((control.Items.IndexOf(item) % 2) == 0) {
            // 計算上は偶数だが、デザイン上は奇数行になるので奇数スタイルを返却
            return OddStyle;
        }
        else {
            // 計算上は奇数だが、デザイン上は偶数行になるので偶数スタイルを返却
            return EvenStyle;
        }
    }
}
' VB.NET
Imports System.Windows
Imports System.Windows.Controls

Public Class ListBoxStyleSelector
    Inherits StyleSelector

    ''' <summary>偶数スタイルを取得・設定します。</summary>
    Public Property EvenStyle() As Style

    ''' <summary>奇数スタイルを取得・設定します。</summary>
    Public Property OddStyle() As Style

    Public Overrides Function SelectStyle(item As Object, container As DependencyObject) As Style
        Dim control = ItemsControl.ItemsControlFromItemContainer(container)
        If control.Items.IndexOf(item) Mod 2 = 0 Then
            ' 計算上は偶数だが、デザイン上は奇数行になるので奇数スタイルを返却
            Return OddStyle
        Else
            ' 計算上は奇数だが、デザイン上は偶数行になるので偶数スタイルを返却
            Return EvenStyle
        End If
    End Function
End Class


XAML です。リソースでのスタイル定義と ListBox.ItemContainerStyleSelector プロパティに注目してください。

<Window x:Class="Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:v="clr-namespace:LivetWPFApplication1.Views"
        Title="一航戦" Height="240" Width="250">
   
    <Window.Resources>
        <!-- 偶数スタイル -->
        <Style TargetType="ListBoxItem" 
               x:Key="even" BasedOn="{StaticResource {x:Type ListBoxItem}}" >
            <Setter Property="Background" Value="AntiqueWhite" />
        </Style>
        <!-- 奇数スタイル -->
        <Style TargetType="ListBoxItem" 
               x:Key="odd" BasedOn="{StaticResource {x:Type ListBoxItem}}" >
            <Setter Property="Background" Value="Aquamarine" />
        </Style>
        <!-- スタイルセレクター -->
        <v:ListBoxStyleSelector x:Key="ListBoxStyleSelector"
            EvenStyle="{StaticResource even}" OddStyle="{StaticResource odd}" />
    </Window.Resources>
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <!-- ListBox のプロパティにスタイルセレクターを設定します -->
        <ListBox ItemContainerStyleSelector="{StaticResource ListBoxStyleSelector}" >
            <ListBoxItem Content="赤城改" />
            <ListBoxItem Content="伊168改" />
            <ListBoxItem Content="加賀改" />
            <ListBoxItem Content="北上改二" />
            <ListBoxItem Content="千代田航改二" />
            <ListBoxItem Content="長門改" />
        </ListBox>
        <Button Grid.Row="1" Height="26" Width="90"
                Content="OK" Margin="10, 10"
                HorizontalAlignment="Right"
                VerticalAlignment="Bottom" />
    </Grid>
</Window>


WPF FAQ の目次に戻る