I have a ListView declared as:
<ListView x:Name="Tree"
ItemsSource="{Binding ElementName=This, Path=Some.Path.Values}"
AlternationCount="2"
ScrollViewer.CanContentScroll="False">
and a style defined as
<UserControl.Resources>
<Style TargetType="ListViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="SteelBlue"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Gray"/>
</Style.Resources>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="White" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="GhostWhite" />
</Trigger>
</Style.Triggers>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<EventSetter Event="Loaded" Handler="ContinueLoading" />
</Style>
This combination produced the original desired behaviour, which is that of alternating background highlights. The new desired behaviour was to change that background color depending on the value of a property of a given ListView item; as such the Style.Triggers was changed to
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="White" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="GhostWhite" />
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="0"/>
<Condition Binding="{Binding Converter={x:Static controls:Converters.ObjectType}}" Value="{x:Type client:DocumentEntryTypeA}" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding Converter={x:Static controls:Converters.LightColor}, UpdateSourceTrigger=PropertyChanged, Path=Status}" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="1"/>
<Condition Binding="{Binding Converter={x:Static controls:Converters.ObjectType}}" Value="{x:Type client:DocumentEntryTypeA}" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{Binding Converter={x:Static controls:Converters.DarkColor}, UpdateSourceTrigger=PropertyChanged, Path=Status}" />
</MultiDataTrigger>
</Style.Triggers>
</UserControl.Resources>
The ObjectType Converter checks that an element is of a given class; the LightColor and DarkColor Converters produce the selected background values depending on the value of the Status property.
The issue with this code is that the binding I use seems to always produce an AlternationIndex value of ‘0’, i.e. the Converter LightColor is used for every entry. In addition to the code above, I have also tried the following bindings with the same result:
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}, Path=AlternationIndex}" Value="0"/>
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}}, Path=(ItemsControl.AlternationIndex)}" Value="0"/>
Based on the examples I’ve seen most of the solutions don’t separate the style from the object; in my case the style is defined separately within UserControl.Resources. However, since using a Trigger works fine, I’m not sure why a DataTrigger does not, or what would be required to get it working.
The first condition in your
MultiDataTriggerfinds the most recentContentPresenter, and tries to bind toContentPresenter.ItemsControl.AlternationIndex, andItemsControl.AlternationIndexis not a valid property forContentPresenter.Try changing that to
RelativeSource={RelativeSource Self}so you will be binding to theItemsControl.AlternationIndexof the current object