New to Telerik UI for .NET MAUI? Start a free 30-day trial

.NET MAUI TemplatedPicker Data Binding

The TemplatedPicker for .NET MAUI provides means for creating a fully-customizable picker control. You can place any list of items inside the popup for the user to choose from and show the selected value in a defined format.

This article describes the TemplatedPicker properties that are used for binding and presenting the selected value, which comes from the selector data source. The selector can be any control shows a list of items user can choose from, for example, CollectionView, RadSpinner, and so on.

  • DisplayMemberPath—Specifies a property of the source object to serve as the visual representation of the selected item.

  • DisplayStringFormat—Enables you to choose what text to display when an item from the selector was picked through the DisplayStringFormat TemplatedPicker property.

  • SelectedValue—Used when you have linked your TemplatedPicker to a data source, and you want to return a value of type object different from the one which is displayed.

Clear Button

You can enable a Clear button which can be used to quickly remove the selected value. To enable the button, set IsClearButtonVisible property of the TemplatedPicker:

<telerik:RadTemplatedPicker IsClearButtonVisible="True" />

Example

The example below uses two RadSpinner controls inside the SelectorTemplate of the TemplatedPicker which present cascading lists of items (the items shown in the second spinner depend on the selected value from the first spinner). Through the SelectedValue and DisplayMemberPath properties you can define how the selection from the spinners is visualized in the picker when the popup is closed.

1. Define the control:

<telerik:RadTemplatedPicker x:Name="picker"
                            SelectedValue="{Binding FromCity, Mode=TwoWay}"
                            DisplayMemberPath="Name"
                            SelectorTemplate="{StaticResource SelectorTemplate}"
                            AutomationId="templatedPicker">
    <telerik:RadTemplatedPicker.PopupSettings>
        <telerik:PickerPopupSettings HeaderTemplate="{StaticResource HeaderTemplate}"/>
    </telerik:RadTemplatedPicker.PopupSettings>
</telerik:RadTemplatedPicker>

2. Define the SelectorTemplate:

<ControlTemplate x:Key="SelectorTemplate">
    <Grid ColumnDefinitions="*, *"
          HeightRequest="250">
        <Grid.Style>
            <OnPlatform x:TypeArguments="Style">
                <On Platform="WinUI">
                    <Style TargetType="Grid">
                        <Setter Property="WidthRequest" Value="{Binding Width, Source={x:Reference picker}}" />
                    </Style>
                </On>
            </OnPlatform>
        </Grid.Style>
        <telerik:RadSpinner x:Name="countriesSpinner"
                            Grid.Column="0"
                            ItemsSource="{Binding Countries}"
                            DisplayMemberPath="Name" />
        <telerik:RadSpinner x:Name="citiesSpinner"
                            Grid.Column="1"
                            ItemsSource="{Binding SelectedItem.Cities, Source={x:Reference countriesSpinner}}"
                            SelectedItem="{TemplateBinding SelectedValue}"
                            DisplayMemberPath="Name" />
    </Grid>
</ControlTemplate>

3. Define the HeaderTemplate:

<ControlTemplate x:Key="HeaderTemplate">
    <Grid BackgroundColor="DarkGray">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Label Text="Origin Country"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               TextColor="White" />
        <Label Grid.Column="1"
               Text="Origin City" 
               HorizontalOptions="Center"
               VerticalOptions="Center"
               TextColor="White" />
    </Grid>
</ControlTemplate>

4. Add the following data item for the first spinner:

public class Country : NotifyPropertyChangedBase
{
    private string name;

    public Country()
    {
        this.Cities = new ObservableCollection<City>();
    }

    public string Name
    {
        get
        {
            return this.name;
        }
        set
        {
            if (value != this.name)
            {
                this.UpdateValue(ref this.name, value);
            }
        }
    }

    public ObservableCollection<City> Cities { get; }
}

5. Add the following data item for the second spinner:

public class City : NotifyPropertyChangedBase
{
    private string name;

    public string Name
    {
        get
        {
            return this.name;
        }
        set
        {
            if (value != this.name)
            {
                this.UpdateValue(ref this.name, value);
            }
        }
    }
}

6. Define the ViewModel:

public class LocationViewModel : NotifyPropertyChangedBase
{
    private Country fromCountry;
    private City fromCity;

    public LocationViewModel()
    {
        this.Countries = new ObservableCollection<Country>
        {
            new Country
            {
                Name = "Austria",
                Cities =
                {
                    new City { Name = "Graz" },
                    new City { Name = "Innsbruck" },
                    new City { Name = "Linz" },
                    new City { Name = "Ratz" },
                    new City { Name = "Salzburg" },
                    new City { Name = "Vienna" },
                    new City { Name = "Wolfsberg" },
                    new City { Name = "Zeltweg" }
                }
            },
            new Country
            {
                Name = "Belgium",
                Cities =
                {
                    new City { Name = "Antwerp" },
                    new City { Name = "Assesse" },
                    new City { Name = "Bruges" },
                    new City { Name = "Charleroi" },
                    new City { Name = "Lint" },
                    new City { Name = "Ranst" },
                    new City { Name = "Schaffen" },
                    new City { Name = "Veurne" },
                    new City { Name = "Zingem" },
                }
            },
            new Country
            {
                Name = "Denmark",
                Cities =
                {
                    new City { Name = "Aalborg" },
                    new City { Name = "Aarhus" },
                    new City { Name = "Billund" },
                    new City { Name = "Copenhagen" },
                    new City { Name = "Karup" },
                    new City { Name = "Odense" },
                    new City { Name = "Viborg" },
                    new City { Name = "Vojens" }
                }
            },
            new Country
            {
                Name = "France",
                Cities =
                {
                    new City { Name = "Aurillac" },
                    new City { Name = "Belley" },
                    new City { Name = "Carcassonne" },
                    new City { Name = "Caen" },
                    new City { Name = "Deauville" },
                    new City { Name = "La Rochelle" },
                    new City { Name = "Nice" },
                    new City { Name = "Marseille" },
                    new City { Name = "Paris" },
                    new City { Name = "Rodez" }
                }
            },
            new Country
            {
                Name = "Germany",
                Cities =
                {
                    new City { Name = "Baden-Baden" },
                    new City { Name = "Berlin" },
                    new City { Name = "Borkum" },
                    new City{ Name = "Bremen" },
                    new City{ Name = "Dortmund" },
                    new City{ Name = "Dresden" },
                    new City{ Name = "Hamburg" },
                    new City{ Name = "Hannover" },
                    new City{ Name = "Leipzig" },
                    new City{ Name = "Mannheim" },
                    new City{ Name = "Munich" },
                    new City{ Name = "Nuremberg" }
                }
            },
            new Country
            {
                Name = "Italy",
                Cities =
                {
                    new City { Name = "Aosta" },
                    new City { Name = "Bari" },
                    new City { Name = "Bologna" },
                    new City { Name = "Parma" },
                    new City { Name = "Rimini" },
                    new City { Name = "Rome" }
                }
            },
            new Country
            {
                Name = "Netherlands",
                Cities =
                {
                    new City { Name = "Amsterdam" },
                    new City { Name = "Bonaire" },
                    new City { Name = "Eindhoven" },
                    new City { Name = "Maastricht" },
                    new City { Name = "Rotterdam" }
                }
            },
            new Country
            {
                Name = "Portugal",
                Cities =
                {
                    new City { Name = "Braga" },
                    new City { Name = "Cascais" },
                    new City { Name = "Lisbon" },
                    new City { Name = "Porto" }
                }
            },
            new Country
            {
                Name = "Spain",
                Cities =
                {
                    new City { Name = "Alicante" },
                    new City { Name = "Barcelona" },
                    new City { Name = "Madrid" },
                    new City { Name = "Seville" },
                    new City { Name = "Valencia" },
                    new City { Name = "Zaragoza" }
                }
            },
            new Country
            {
                Name = "United Kingdom",
                Cities =
                {
                    new City { Name = "Bristol" },
                    new City { Name = "Liverpool" },
                    new City { Name = "London" },
                    new City { Name = "Manchester" },
                    new City { Name = "Norwich" },
                    new City { Name = "Southampton" }
                }
            },
        };
    }

    public Country FromCountry
    {
        get
        {
            return this.fromCountry;
        }
        set
        {
            if (value != this.fromCountry)
            {
                this.UpdateValue(ref this.fromCountry, value);
            }
        }
    }

    public City FromCity
    {
        get
        {
            return this.fromCity;
        }
        set
        {
            if (value != this.fromCity)
            {
                this.UpdateValue(ref this.fromCity, value);
            }
        }
    }

    public ObservableCollection<Country> Countries { get; }
}

7. Set the defined LocationViewModel as a BindingContext of the page:

this.BindingContext = new LocationViewModel();

8. In addition to this, you need to add the following namespace:

xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"

The following image shows the end result.

TemplatedPicker Selected Value

See Also

In this article