Corrado's Blog 2.0

Online thoughts of a technology funatic

Xamarin Forms: CarouselView in action

Xamarin Forms are getting better with each new release, version 2.2, actually in preview, includes new interesting addition like Effects and CarouselView.

CarouselView replaces the now deprecated CarouselPage with a more flexible control that can be embedded in any page and can have any size you want, being curious I wanted to see it in action.

I created a new Xamarin Forms project and updated all projects NuGet Packages to version 2.2.0.5-pre2 (you have to select “Include prerelease” option to have it listed since, at the moment, it hasn’t officially released yet.

image

I suddenly added a MainView xaml page to the PCL project and set it as MainPage inside App.cs

public class App : Application { public App() { // The root page of your application MainPage = new MainView(); } }

CarouselView inherits from ItemView so it requires a collection of items associated to it’s ItemSource property, I then created an array of Persons and associated to CarouselView with this code

public partial class MainView : ContentPage { public MainView() { this.InitializeComponent(); Person[] persons = { new Person() { Name = "Corrado", ImageUri = "male.png" }, new Person() { Name = "Giulia", ImageUri = "female.png" } }; this.MyCarouselView.ItemsSource = persons; CarouselView v; } } public class Person { public string Name { get; set; } public string ImageUri { get; set; } }

MyCarouselView is the CarouselView I previously added to MainView.xaml:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:testCarouselView="clr-namespace:TestCarouselView;assembly=TestCarouselView" x:Class="TestCarouselView.MainView"> <CarouselView x:Name="MyCarouselView" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" /> </ContentPage>

Great, but we’re missing something: The ItemTemplate. but since I want to use a different template for each page I decided to use another recent addition to Xamarin Forms: the DataTemplateSelector, so I created this class that inherits from abstract DataTemplateSelector.

public class CarouselTemplateSelector : DataTemplateSelector { public DataTemplate MaleTemplate { get; set; } public DataTemplate FemaleTemplate { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { Person person = (Person)item; switch (person.ImageUri) { case "male.png": return MaleTemplate; case "female.png": return FemaleTemplate; default: throw new ArgumentOutOfRangeException(); } } }

So simple that don’t think it requires a detailed explanation, it just returns proper DataTemplate depending on the name of ImageUri, ok, not very professional but this is just a demo right? Smile

I generally like to have TemplateSelectors instantiated via xaml together with their associated template definition in one place, so I added them to MainView xaml resources, here’s complete markup:

<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:testCarouselView="clr-namespace:TestCarouselView;assembly=TestCarouselView" x:Class="TestCarouselView.MainView"> <ContentPage.Resources> <ResourceDictionary> <!--Female template--> <DataTemplate x:Key="FeMaleTemplate"> <StackLayout BackgroundColor="Pink" Orientation="Horizontal"> <Image Source="{Binding ImageUri}" VerticalOptions="Center" Margin="50,0,0,0" WidthRequest="100" HeightRequest="200" /> <Label VerticalOptions="Center" Margin="60,0,0,0" Text="{Binding Name}" TextColor="Black" FontSize="30" /> </StackLayout> </DataTemplate> <!--Male template--> <DataTemplate x:Key="MaleTemplate"> <Grid BackgroundColor="Aqua"> <Image Source="{Binding ImageUri}" VerticalOptions="Start" Margin="00,50,0,0" WidthRequest="100" HeightRequest="200" /> <Label VerticalOptions="Center" HorizontalOptions="Center" Margin="0,500,0,0" Text="{Binding Name}" TextColor="Black" FontSize="30" /> </Grid> </DataTemplate> <!--Template selector--> <testCarouselView:CarouselTemplateSelector x:Key="CarouselTemplateSelector" MaleTemplate="{StaticResource MaleTemplate}" FemaleTemplate="{StaticResource FeMaleTemplate}" /> </ResourceDictionary> </ContentPage.Resources> <!--Carousel View--> <CarouselView PositionSelected="OnPositionSelected" x:Name="MyCarouselView" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemTemplate="{StaticResource CarouselTemplateSelector}" /> </ContentPage>

From the xaml you’ll immediately recognize the two (simple) DataTemplates, the custom DataTemplateSelector , how it gets associated to CarouselView ItemTemplate but if you look closely you’ll also recognize a nice addition to Forms v2.2: Margin property!

Yes we can now stop using nested views with Padding to fine tune control position inside a Page, well done Xamarin!

If you want to be informed when the position of CarouselView changes just subscribe PositionChanged event, in my case I mapped it to this method:

private void OnPositionSelected(object sender, SelectedPositionChangedEventArgs e) { Debug.WriteLine(e.SelectedPosition.ToString()); }

We can now run the sample code and we’ll get this outputs (Android/iOS)

Android       ios

CarouselView is a great new entry, in special case if you want to create applications based on sliding views (quite common today) there’s just one feature I miss: Orientation, at the moment looks like you can only slide horizontally, hope Xamarin will consider it for final release.