Very quick Xamarin How-To this week with a simple converter. Alternating row colours in a CollectionView is quite often a design requirement and I wanted to create a simple, reusable converter to solve this.
The Converter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System; using System.Globalization; using System.Linq; using Xamarin.Forms; using Xamarin.Forms.Internals; namespace XhtCollectionViewAlternatingRowColor.Converters { public class IndexToColorConverter : IValueConverter { public Color EvenColor { get; set; } public Color OddColor { get; set; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var collectionView = parameter as CollectionView; return collectionView.ItemsSource.Cast<object>().IndexOf(value) % 2 == 0 ? EvenColor : OddColor; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } } |
Using the Converter in XAML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage Title="Alternating Row Colors" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:converters="clr-namespace:XhtCollectionViewAlternatingRowColor.Converters" xmlns:local="clr-namespace:XhtCollectionViewAlternatingRowColor" x:Class="XhtCollectionViewAlternatingRowColor.MainPage"> <ContentPage.Resources> <converters:IndexToColorConverter x:Key="IndexToColorConverterGrid" EvenColor="#0D92DB" OddColor="White"/> <converters:IndexToColorConverter x:Key="IndexToColorConverterText" EvenColor="White" OddColor="Black"/> </ContentPage.Resources> <ContentPage.BindingContext> <local:MainViewModel/> </ContentPage.BindingContext> <ContentPage.Content> <CollectionView x:Name="MyCollectionView" ItemsSource="{Binding Items}"> <CollectionView.ItemTemplate> <DataTemplate> <Grid BackgroundColor="{Binding ., Converter={StaticResource IndexToColorConverterGrid}, ConverterParameter={x:Reference MyCollectionView}}"> <Label Text="{Binding .}" TextColor="{Binding ., Converter={StaticResource IndexToColorConverterText}, ConverterParameter={x:Reference MyCollectionView}}" Margin="20"/> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </ContentPage.Content> </ContentPage> |
There you go, nice and simple, easy to follow and reuse! As always full source code available here.
Despite the fact that it works great, the ToList copy in each call of the converter seems a really bad example. A list of 10 items would create 20 list copies in your example.
I think it would be way cleverer to type check it and cast it to prevent all those allocations that on mobile are really not nessecary.
but none the less. a cool sample! keep up the cool blogs
Hi Bernhard,
That’s a very good point you make! I have updated the solution accordingly.