I have listbox control which has list of colors. Here is code and Image:
<ListBox Name="FillSelections" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Center" SelectedItem="{Binding SelectedColor}" SelectionMode="Single" Style="{StaticResource HorizontalListBoxStyle}" ItemsSource="{Binding FillColors}" ItemTemplate="{StaticResource ColorsItemTemplate}"></ListBox>
<DataTemplate x:Key="ColorsItemTemplate">
<Border BorderBrush="Transparent">
<Rectangle Width="20" StrokeThickness="1" Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{Binding}" />
</Rectangle.Fill>
</Rectangle>
</Border>
Image:
How would I change style of last item only like this:
This can be achieved through converter which do the work of finding if its last item in the listbox -
Converter
public class IsLastItemInContainerConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
DependencyObject item = (DependencyObject)value;
ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
return ic.ItemContainerGenerator.IndexFromContainer(item)
== ic.Items.Count - 1;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And using that you can set the DataTemplate in your xaml class like this -
<ListBox ItemContainerStyle="{StaticResource ColorsItemStyle}"/>
<Style x:Key="ColorsItemStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
Converter={StaticResource IsLastItemInContainerConverter}}" Value="False">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate></DataTemplate> // Your template goes here
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
Converter={StaticResource IsLastItemInContainerConverter}}" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate></DataTemplate> // Your lastItem template goes here
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
to get this to work w/ a ListBox that changes over time I ended up using a MultiBinding:
<DataTemplate x:Key="myItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}"/>
<TextBlock x:Name="dots" Text="..."/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource isLastItemInContainerConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBoxItem}" />
<Binding Path="Items.Count" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}" />
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="dots" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Note: the second binding is only used to get notified when the list changes
here is the corresponding MultivalueConverter
public class IsLastItemInContainerConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
DependencyObject item = (DependencyObject)values[0];
ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
return ic.ItemContainerGenerator.IndexFromContainer(item) == ic.Items.Count - 1;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With