V tom případě nabízím alternativní řešení, ačkoliv si nejsem jistý, jestli je úplně elegantní. Pravděpodobně by se to dalo udělat lépe, případně mě někdo jistě opraví. 1.) Vytvořte si třídu AlternationIndexToBooleanConverter
Public Class AlternationIndexToBooleanConverter
Implements IMultiValueConverter
Public Function Convert(values() As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
Dim limit As Integer
If values.Length = 2 AndAlso TypeOf values(0) Is ListBoxItem AndAlso Integer.TryParse(values(1), limit) Then
Dim index = ItemsControl.GetAlternationIndex(DirectCast(values(0), ListBoxItem))
Return index <= limit
End If
Return False
End Function
Public Function ConvertBack(value As Object, targetTypes() As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
Return Enumerable.Empty(Of Object)()
End Function
End Class
2.)Přidejte tento Converter to Application.xaml:
<Application StartupUri="MainWindow.xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:..." xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Application">
<Application.Resources>
<local:AlternationIndexToBooleanConverter x:Key="AlternationIndexToBooleanConverter" />
</Application.Resources>
</Application>
Jmenný prostor xmlns:local si přepiště na jmenný prostor, kde se nachází ta třída converteru. U mně to je clr-namespace:SandboxWpfVb, protože jsem třídu nedal do žádného speciálního jmenného prostoru a globální namespace je nastaven na SandboxWpfVb. U Vás to může být třeba MyAwesomeProject.Converters. 3.) A pak už jen použití:
<Window DataContext="3" Height="320" Width="240" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:system="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MainWindow">
<ListBox AlternationCount="{x:Static system:Int32.MaxValue}">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource AlternationIndexToBooleanConverter}">
<Binding RelativeSource="{RelativeSource Mode=Self}" />
<Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
<ListBoxItem Content="1" />
<ListBoxItem Content="2" />
<ListBoxItem Content="3" />
<ListBoxItem Content="4" />
<ListBoxItem Content="5" />
<ListBoxItem Content="6" />
<ListBoxItem Content="7" />
</ListBox>
</Window>
Jak jistě vidíte, funguje to tak, že DataTrigger dostane MultiBinding, který je vyhodnocovaný naším Converterem. Ten dostane několik hodnot, zkontroluje jejich rozsahy (2 hodnoty, jednou ListBoxItem a pak číslo) a zjistí index položky v ListBoxu. Vrácený výsledek je pak porovnání indexu vůči limitu. ListBox musí mít nastavený AlternationCount (zase na Integer.MaxValue), jinak indexy budou vždy 0 a obarví se Vám vše. Limit, tedy druhá hodnota do Converteru je nastaven na DataContext okna, ale je možné ho nastavit na cokoliv jiného (typicky na nějakou vlastnost DataContextu místo celého DataContextu).
|