Maui (net8), Xamarin Forms, Native (xamarin & .net8) - iOS + Android |
---|
Definition from Apple 🍏 :
A Wheel Picker is a view that uses a spinning-wheel or slot-machine metaphor to display one or more sets of values.
This interactive UI control mimics a slot machine user interface on Android, while on iOS, it makes it easy to use multi-wheel pickers.
Enterprise support available: contact sales
Source code available: contact sales
WheelPicker
(hot reload & trimming enabled)vapolia.WheelPicker
(can be used in layout .xml files) UIPickerViewModel
(can be used in storyboards)dotnet add package Vapolia.WheelPicker
If using Maui, register the control in the CreateMauiApp()
function:
...
using Vapolia.WheelPickers;
...
builder
.UseMauiApp<App>()
.UseWheelPicker();
xmlns:wp="https://vapolia.eu/WheelPicker"
to the root tag<wp:WheelPicker ItemsSourceSimple="{Binding MyListProperty}">
<wp:WheelDefinition Width="Auto" HorizontalOptions="Left" Alignment="Center" />
</wp:WheelPicker>
The WheelPicker is made of 2 parts:
<wp:WheelPicker> ... </wp:WheelPicker>
which contains 1 or more wheels and present them like a Horizontal StackLayout does.wp:WheelDefinition
, each representing a vertical interactive wheel.wp:WheelDefinition
has a customizable template to display each item of the wheel.The WheelPicker is bound to a single data source through ItemsSource="{Binding SomeProperty}"
.
The type of SomeProperty
can be:
For 1 wheel:
IReadOnlyCollection<T>
. Ex: List<string>
For more than 1 wheel:
IReadOnlyCollection<IReadOnlyCollection<T>>
. Ex: List<List<MyItemModel>>
wp:WheelDefinition
.<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:wp="clr-namespace:Vapolia.WheelPickers;assembly=Vapolia.WheelPicker"
x:Class="WheelPickerDemo.Forms.MainPage">
<VerticalStackLayout>
<wp:WheelPicker HorizontalOptions="Fill" SelectedItemsIndex="0"
ItemsSource="{Binding Days}"
Command="{Binding ItemSelectedCommand}">
<wp:WheelDefinition Width="Auto" HorizontalOptions="Left" Alignment="Center" />
</wp:WheelPicker>
</VerticalStackLayout>
</ContentPage>
In the code behind, set the binding context to your view model containing the items to display.
For the example below ItemsSource
is bound to a list of strings.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageModel();
}
}
public class MainPageModel
{
public List<string> Days { get; } = new () { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
public Command ItemSelectedCommand { get; }
public MainPageModel()
{
//Component is the index of the wheel triggering the command.
//Row is the index of the currently displayed item at the center of the wheel for this Component.
//ItemIndexes are the current indexes of all wheels of the WheelPicker control
ItemSelectedCommand = new Command<(int Component, int Row, IList<int> ItemIndexes)>(tuple =>
{
var selectedValue = Days[tuple.Row];
//...
});
}
}
You can customize how each item is rendered by using custom templates.
By default, the control converts all items to strings and renders those strings with the specified style.
You can fully customize the style and content of the items. However, there is a constraint: there is only one template per wheel, which renders all items of that wheel. If you have multiple wheels in the same WheelPicker, you can set one template per wheel.
For example, below is a templated picker with 3 wheels. All properties are bindable and can be dynamically changed.
Note how SelectedItemsIndex
is used to initialize the position of the 3 wheels to the specified item indexes.
<wp:WheelPicker x:Name="SlotPicker" ItemsSource="{Binding Slot.ItemsSource}"
SelectedItemsIndex="1 10 7"
Command="{Binding Slot.ItemSelectedCommand}"
ItemTextSelectedColor="Lime"
ItemTextFont="Italic"
HorizontalOptions="Fill"
SelectionLinesColor="Aquamarine">
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True">
<DataTemplate>
<Label Text="{Binding .}" TextColor="Black" FontSize="30" />
</DataTemplate>
</wp:WheelDefinition>
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True" RowHeight="100">
<DataTemplate>
<Image Source="{Binding .}" HeightRequest="100" Aspect="AspectFit" />
</DataTemplate>
</wp:WheelDefinition>
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True" RowHeight="100">
<DataTemplate>
<Image Source="{Binding .}" HeightRequest="100" Aspect="AspectFit" />
</DataTemplate>
</wp:WheelDefinition>
</wp:WheelPicker>
Those examples are extracted from the demo projects in this repository.
A simple picker with one wheel:
<wp:WheelPicker ItemsSource="{Binding DayPicker.ItemsSource}">
<wp:WheelDefinition Width="Auto" HorizontalOptions="Left" Alignment="Center" />
</wp:WheelPicker>
A templated picker with one wheel:
<wp:WheelPicker ItemsSource="{Binding DayPicker.ItemsSource}">
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True" RowHeight="48">
<DataTemplate>
<Image Source="{Binding .}" HeightRequest="48" Aspect="AspectFill" />
</DataTemplate>
</wp:WheelDefinition>
</wp:WheelPicker>
A picker with 3 wheels:
The width of the center wheel is computed automatically, and items are aligned differently inside each wheel.
<wp:WheelPicker SelectionLinesColor="Navy"
HorizontalSpaceBetweenWheels="40"
ItemsSource="{Binding DatePicker.ItemsSource}"
SelectedItemsIndex="0,0,0"
Command="{Binding DatePicker.ItemSelectedCommand}"
HorizontalOptions="Fill">
<wp:WheelDefinition Width="*" HorizontalOptions="Right" />
<wp:WheelDefinition Width="Auto" HorizontalOptions="Left" />
<wp:WheelDefinition Width="*" HorizontalOptions="Left" />
</wp:WheelPicker>
A templated picker with 3 wheels:
All properties are bindable and can be dynamically changed.
<wp:WheelPicker x:Name="SlotPicker" ItemsSource="{Binding Slot.ItemsSource}"
SelectedItemsIndex="0 0 0"
Command="{Binding Slot.ItemSelectedCommand}"
ItemTextSelectedColor="Lime"
ItemTextFont="Italic"
HorizontalOptions="Fill"
SelectionLinesColor="Aquamarine">
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True" RowHeight="100">
<DataTemplate>
<Image Source="{Binding .}" HeightRequest="100" Aspect="AspectFit" />
</DataTemplate>
</wp:WheelDefinition>
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True" RowHeight="100">
<DataTemplate>
<Image Source="{Binding .}" HeightRequest="100" Aspect="AspectFit" />
</DataTemplate>
</wp:WheelDefinition>
<wp:WheelDefinition Width="*" HorizontalOptions="Left" Alignment="Center" IsCircular="True" RowHeight="100">
<DataTemplate>
<Image Source="{Binding .}" HeightRequest="100" Aspect="AspectFit" />
</DataTemplate>
</wp:WheelDefinition>
</wp:WheelPicker>
The Wheel Picker provides an event and a Command when the selection changes, making it easy to use with or without mvvm frameworks.
It also implements INotifyPropertyChanged
.
This control supports hot reload and live preview.
Enterprise support is available: contact sales
Source code is available: contact sales