WPF 3.5 SP1の新機能 - AlternationCount

WPF 3.5 SP1 Feature: Alternating Rows – Vincent Sibal's Blog



WPF 3.5 SP1 BetaのItemsControlには、AlternationCountプロパティとAlternationIndexプロパティが追加されています。この2つのプロパティを利用することで、一行おきに色を変更するといったことが非常に簡単に実現できるようになります。


Visual Basic( Window1.xaml.vb

Class Window1
 
    Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Dim ListData As New ObjectModel.ObservableCollection(Of String)
        For i = 0 To 99
            ListData.Add("テストデータ" + i.ToString())
        Next
        ListBox1.ItemsSource = ListData
    End Sub
 
End Class


XAMLWPF
<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300" Loaded="Window1_Loaded">
    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
                <Style.Triggers>
                    <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                        <Setter Property="Background" Value="LightBlue"/>
                    </Trigger>
                    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                        <Setter Property="Background" Value="Gray"/>
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>
        <ListBox Name="ListBox1" AlternationCount="2"/>
    </Grid>
</Window>





AlternationCountプロパティで指定した行数毎にスタイルを繰り返すというイメージになります。AlternationCountプロパティ値が2の場合、AlternationIndexプロパティの値は0,1,0,1,0…というように変化していきます。


AlternationIndexプロパティは添付プロパティであるため、ItemsControl以外の場所でも値を共有(参照)することが可能になっています。


TriggerではなくBindingから利用するような方法も考えられます。


Visual Basic( EvenConverter.vb
Class EvenConverter
    Implements IValueConverter
 
    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
        Select Case value
            Case 0
                Convert = True
            Case 1
                Convert = False
            Case Else
                Convert = Nothing
        End Select
    End Function
 
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class


XAML( WPF )
<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:AlternatingRows"
   Title="Window1" Height="300" Width="300" Loaded="Window1_Loaded">
    <Grid>
        <Grid.Resources>
            <local:EvenConverter x:Key="EvenConverter"/>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <StackPanel Orientation="Horizontal">
                                <CheckBox IsChecked="{TemplateBinding ItemsControl.AlternationIndex, Converter={StaticResource EvenConverter}}"/>
                                <TextBlock Text="{TemplateBinding Content}"/>
                            </StackPanel>
                        </ControlTemplate>       
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <ListBox Name="ListBox1" AlternationCount="2"/>
    </Grid>
</Window>