Change the style of the last item in a ListBox

I have a list control that has a list of colors. Here is the 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> 

Picture:

image

How to change the style of the last element only as follows:

image

+7
source share
2 answers

This can be achieved using a converter that searches if its last item in the list is

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 this, you can set the DataTemplate in your xaml class as follows:

 <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> 
+19
source

To get this to work with a ListBox that changes over time, I ended up using 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 receive notification 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(); } } 
+6
source

All Articles