Using native wheel picker in Xamarin Forms — UI Day 1

This article is part of a serie dedicated to xamarin forms UI controls that i find valuable to use in my customer’s projects.

Benjamin Mayrargue
Feb 10 · 7 min read

Have you ever remarked the gorgeous wheel picker used in lots of AppStore apps? Did you ever wanted to use it in the Xamarin Forms project of your customer so you can hear Ohhs and Ahhs from your work? Did you feel bad when you discovered this control does not come out of the box of Xamarin Forms, and no-one seems to have created one on github, and that finally you decided to put an horrible list picker instead ?

On Apple’s world, the wheelpicker is a well documented, not easy to use, but so cutely designed UI control from which the user can quickly and intuitively select linked values, like a date : a birth date, a driver license’s date (month day year values); or a vehicle’s details (brand, model, year) for examples. You can also use it to select a single value in an easy way, even in a large list, thanks to the “flying” acceleration feature, simulating the inertia of a heavy wheel that you spin with force. In this last case, the addition of a search or filter input could also have some benefits.

Anatomy of a wheel

A wheel is made of wheel parts. For example a date picker will have the month, day and year parts. Each part can be spinned independently of each other. You can also add business rules between parts, which makes sense when selecting a date: you really don’t want the 31th of February selected, do you ? 🙄

A quick example of a rule that coud be set on a date wheel picker: when the selected day is 31 then verify that the selected month has 31 days; otherwise programatically move the “month” wheel part to the next month having 31 days.

A wheel with 3 parts
A wheel with 1 part

Each part of the wheel is made of a list of the same templated item reflecting the bounded enumerable property. You define this template once for each part. Among the part’s item template properties, the most useful is its alignment. But there are lots more like Color and Font.

The slide-up wheel picker is the one you see in most AppStore’s apps. The wheel control is embedded in a semi-transparent page having a slide-up transition. The control has a fixed height. But you can integrate it as you want, for example anywhere in a scrolling form page.

A wheel in a form
A wheel in a slide-up

Using the wheel control

Wizard checklist:

  • install the wheel picker extension for visual studio (coming soon)
  • use the new assistant installed by this extension to add the xaml and the code for one of the predefined wheelpicker, which is a also good start for any customization.

Manual checklist:

  • Add the wheel nuget to your xamarin forms project
  • Design the wheel in XAML
  • Add code to bind the list of items and handle user interaction

You may prefer to use existing code that match your use case. You will find the most common use cases in the https://github.com/softlion/WheelPicker-Samples repository:

  • a date picker,
  • a date+time picker,
  • a language picker,
  • a country picker,
  • a country+phone number picker (with country code and phone validation)

Note: this control use data binding, which is the best practice and a well known design pattern. If you are new to Xamarin, new to design patterns, or new to data binding, i suggest you read carefully this short tutorial.

Adding the wheel picker using the wizard

Coming soon!

Manually adding the wheel picker

Adding the wheel control

Using the package manager console:

Install-Package Vapolia.WheelPicker.Free 

You can also use the graphical “manage nuget packages” window of Visual Studio.

Designing the wheel

First declare the namespace of the control:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:wp="clr-namespace:Vapolia.WheelPickerForms;assembly=Vapolia.WheelPickerForms"
x:Class="WheelPickerDemo.Forms.MainPage">

Next add the wheel control:

<wp:WheelPicker HorizontalOptions="Fill" ItemsSourceSimple="{Binding Days}" ItemTextFont="Medium">
<wp:WheelDefinition Width="Auto" HorizontalOptions="Left" Alignment="Center" />
</wp:WheelPicker>

Optionally design the wheel’s parts. This is the same experience as creating a cell’s template for a CollectionView or a ListView, with additional properties on the wp:WheelDefinition tag.

<wp:WheelPicker ItemsSourceSimple="{Binding Days}" SelectedItemsIndex="1">
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True">
<wp:WheelDefinition.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}" />
</DataTemplate>
</wp:WheelDefinition.ItemTemplate>
</wp:WheelDefinition>
</wp:WheelPicker>

Remark the IsCircular property which makes a wheel’s part circular, which means it will go back to the 1st item after the last item is displayed. It’s like an infinite list, or a real wheel after a complete wheel turn. Without this property, the wheel stops spinning on the last item.

Displaying items

This is a very simple codebehind file following the recommanded design pattern. It defines MainPageModel as the context (or ambiant) property in the xaml file. MainPageModel is called a view model.

public partial class MainPage : ContentPage
{
public MainPage()
{
BindingContext = new MainPageModel();
InitializeComponent();
}
}

In the MainPageModel class, the Days property is bound to the control’s ItemsSourceSimple property. ItemsSourceSimple is of type IList<object>. Each object in this list becomes the context of the item’s template (referenced by the dot in the code “{Binding .}”), which will display a different cell content each turn.

It is nothing fancy, just standard XAML item template. New to this ? Check this small tutorial.

Important: the bounded list (Days) MUST be directly convertible to IEnumerable<object>. It could be List<object>, ObservableCollection<object>, but NOT List<string> !

Getting the selected value

After the user changed a wheel’s value, the Command is called on the bound model.

<wp:WheelPicker Command="{Binding ItemSelectedCommand}">

The updated code looks like this:

public class MainPageModel
{
public IList<object> Days { get; } = new List<object>
{
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
};

ItemSelectedCommand is triggered each time the user changed a wheel’s part value. It provides 3 parameters:

1) selectedWheelIndex the wheel’s part index where the change occured,

2) selectedItemIndex the index of the new selected item inside this weel’s part,

3) selectedItemsIndex a summary of which item is selected in each wheel’s part.

It is an array of integers, the array lenght is the number of wheel’s part, and each value is the index of the selected item inside this wheel’s part.

Et voila!

You can bind the SelectedItemsIndex property directly instead of a command. But using the command, you can change the items of another wheel’s part based on the user selection. This is demonstrated in the next chapter.

Increasing the number of wheel’s parts

You can add more than one WheelDefinition tag to create a multi-parts wheel. This code demonstrates how to create a wheel with two parts, Month and Day:

<wp:WheelPicker HorizontalOptions="Fill" ItemsSource="{Binding MyWheelItems}"
Command="{Binding ItemsSelectedCommand}">

There are tricky alignments properties there. You can decide how a wheel’s part should align inside the wheel, and how a wheel part’s content (the DataTemplate) should align inside its part.

The Width property defines the relative width of each part within the whole wheel. HorizontalOptions defines how this part align within the whole wheel, if there is spare space left.

Alignment defines how the part’s content align within the part, if there is spare space left on an item.

Dynamically updating the wheel’s items

When a wheel has 2 parts, you can change the items in a part based on the other part’s value. For example, when February is selected and the year is not bissextile, you want to display only 1 to 28 for the days.

You can do this easily. Sample code:

public partial class MainPage : ContentPage
{
public MainPage()
{
BindingContext = new DayMonthModel();
InitializeComponent();
}
}

The wheel picker control will automatically detect the changes inside each ObservableCollection, and will reflect that change in the UI.
If the removed item was selected, the wheel will smoothly spin to the nearest available value.

I hope you enjoyed this article. Please share your thoughts!
Coming soon: using the wheelpicker wizard visual studio plugin.
Benjamin.

References

Also worth reading

Benjamin Mayrargue

Written by

https://www.linkedin.com/in/benjaminmayrargue/

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade