Dropdown Control In Xamarin.Forms - Part One

In this article, you will learn about dropdown control in Xamarin.Forms.

Dropdown Control In Xamarin.Forms
 

Introduction

 
In this article, we will learn how to create a DropDown in Xamarin.Forms. By default, Android Platform has a dropdown called “Spinner”, but iOS Platform has no dropdowns like Android Spinner. In Xamarin.Forms, we have a control called Picker and we all have heard about this. We are going to create a custom dropdown to achieve control like Android Spinner in Xamarin.Forms.
 

Dropdown in Xamarin.Forms

 
As per the introduction, we already have a dropdown control called “Spinner” in Android Platform. Basically, Xamarin.Forms control is a wrapper to platform-specific controls. For example, Xamarin.Forms Entry is a wrapper of EditText in Android and UITextField in iOS.
We will go for View Renderer approach to have a new control to wrap a platform-specific control. Click the below link to know more about View Renderer.
 
Reference
 
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/view
Without much introduction, we will skip into the coding part of this article.
 

Coding Part

 
Here, I will explain the steps to create a DropDown in Xamarin.Forms.
  • Step 1: Creating a new Xamarin.Forms Projects.
  • Step 2: Creating a Dropdown view in Xamarin.Forms .NET Standard Project
  • Step 3: Wrapping Spinner for Dropdown control in Android project.
  • Step 4: Implementation of the dropdown and its demo for Android platform.

Step 1 - Creating a new Xamarin.Forms Project

 
Create a new project by selecting New >> Project >> Xamarin Cross-Platform App and click OK.
 
Dropdown Control In Xamarin.Forms
 
Select Android and iOS Platforms, as shown below with Code Sharing Strategy as PCL or .NET Standard and click OK.
 
Dropdown Control In Xamarin.Forms
 

Step 2 - Creating a Dropdown View in Xamarin.Forms .NET Standard Project

 
In this step, we will see how to create a dropdown view with the required properties.
  1. Create a class named “Dropdown” and inherit the Dropdown with “View”. That means the Dropdown is the child of View.
    1. public class Dropdown : View  
    2. {  
    3.     //...  
    4. }  
  1. Then, we will create the required bindable properties. First, we will see what are all the properties and events required for dropdown.

    • ItemsSource - To assign the list of data to be populated in the dropdown.
    • SelectedIndex - To identify the index of selected values from the ItemsSource.
    • ItemSelected - Event for performing an action when the item selected in the dropdown.

  2. Create a bindable property for the ItemsSource as shown in below.
    1. public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(  
    2.     propertyName: nameof(ItemsSource),  
    3.     returnType: typeof(List<string>),  
    4.     declaringType: typeof(List<string>),  
    5.     defaultValue: null);  
    6.   
    7. public List<string> ItemsSource  
    8. {  
    9.     get { return (List<string>)GetValue(ItemsSourceProperty); }  
    10.     set { SetValue(ItemsSourceProperty, value); }  
    11. }  
  1. Create a bindable property for the SelectedIndex, as shown below.
    1. public static readonly BindableProperty SelectedIndexProperty = BindableProperty.Create(  
    2.     propertyName: nameof(SelectedIndex),  
    3.     returnType: typeof(int),  
    4.     declaringType: typeof(int),  
    5.     defaultValue: -1);  
    6.   
    7. public int SelectedIndex  
    8. {  
    9.     get { return (int)GetValue(SelectedIndexProperty); }  
    10.     set { SetValue(SelectedIndexProperty, value); }  
    11. }  
  1. Create a custom event ItemSelected for dropdown control and invoke the event, as shown below.
    1. public event EventHandler<ItemSelectedEventArgs> ItemSelected;  
    2. public void OnItemSelected(int pos)  
    3. {  
    4.     ItemSelected?.Invoke(thisnew ItemSelectedEventArgs() { SelectedIndex = pos });  
    5. }  
  1. Here, ItemSelectedEventArgs is a child of EventArgs, as shown below.
    1. public class ItemSelectedEventArgs : EventArgs  
    2. {  
    3.     public int SelectedIndex { getset; }  
    4. }  

Full Code of Dropdown View

Here, we will see the full code for dropdown view.
  1. namespace XF.Ctrls  
  2. {  
  3.     public class Dropdown : View  
  4.     {  
  5.         public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(  
  6.             propertyName: nameof(ItemsSource),  
  7.             returnType: typeof(List<string>),  
  8.             declaringType: typeof(List<string>),  
  9.             defaultValue: null);  
  10.   
  11.         public List<string> ItemsSource  
  12.         {  
  13.             get { return (List<string>)GetValue(ItemsSourceProperty); }  
  14.             set { SetValue(ItemsSourceProperty, value); }  
  15.         }  
  16.   
  17.         public static readonly BindableProperty SelectedIndexProperty = BindableProperty.Create(  
  18.             propertyName: nameof(SelectedIndex),  
  19.             returnType: typeof(int),  
  20.             declaringType: typeof(int),  
  21.             defaultValue: -1);  
  22.   
  23.         public int SelectedIndex  
  24.         {  
  25.             get { return (int)GetValue(SelectedIndexProperty); }  
  26.             set { SetValue(SelectedIndexProperty, value); }  
  27.         }  
  28.   
  29.         public event EventHandler<ItemSelectedEventArgs> ItemSelected;  
  30.   
  31.         public void OnItemSelected(int pos)  
  32.         {  
  33.             ItemSelected?.Invoke(thisnew ItemSelectedEventArgs() { SelectedIndex = pos });  
  34.         }  
  35.     }  
  36.   
  37.     public class ItemSelectedEventArgs : EventArgs  
  38.     {  
  39.         public int SelectedIndex { getset; }  
  40.     }  
  41. }  

Step 3 - Wrapping Spinner for Dropdown control in Android Project

 
In this step, we will see how to wrap the Android Spinner Control for Dropdown View.
  1. Create a class file named as “DropdownRenderer” in your Android client project and add a View Renderer.
    1. public class DropdownRenderer : ViewRenderer<Dropdown, Spinner>  
    2. {  
    3.     Spinner spinner;  
    4.     public DropdownRenderer(Context context) : base(context)  
    5.     {  
    6.   
    7.     }     
    8.     // ...  
    9. }  
  1. Then, override the methods “OnElementChanged” and “OnElementPropertyChanged”. OnElementChanged method is triggered on element/control initiation. OnElementPropertyChanged method is called when the element property changes.

  2. Set Native Control to ViewRenderer using SetNativeControl() method in OnElementChanged override method as shown in below.
    1. protected override void OnElementChanged(ElementChangedEventArgs<Dropdown> e)  
    2. {  
    3.     base.OnElementChanged(e);  
    4.   
    5.     if (Control == null)  
    6.     {  
    7.         spinner = new Spinner(Context);  
    8.         SetNativeControl(spinner);  
    9.     }  
    10.     //...  
    11. }  
  1. Set Items Source from Xamarin.Forms Dropdown to Android Spinner control using array adapter, as shown in below.
    1. var view = e.NewElement;  
    2. ArrayAdapter adapter = new ArrayAdapter(Context, Android.Resource.Layout.SimpleListItem1, view.ItemsSource);  
    3. Control.Adapter = adapter;  
  1. Set default selection of item from selected index.
    1. if (view.SelectedIndex != -1)  
    2. {  
    3.     Control.SetSelection(view.SelectedIndex);  
    4. }  
  1. Create an item selected event for spinner and invoke the dropdown event created.
    1. // ...  
    2. Control.ItemSelected += OnItemSelected;  
    3. // ...  
    4. private void OnItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)  
    5. {  
    6.     var view = Element;  
    7.     if (view != null)  
    8.     {  
    9.         view.SelectedIndex = e.Position;  
    10.         view.OnItemSelected(e.Position);  
    11.     }  
    12. }  
  1. In the same way, we will assign ItemsSource & SelectedIndex to Android Spinner when the property changes using OnElementPropertyChanged, as shown below.
    1. protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)  
    2. {  
    3.     var view = Element;  
    4.     if (e.PropertyName == Dropdown.ItemsSourceProperty.PropertyName)  
    5.     {  
    6.         ArrayAdapter adapter = new ArrayAdapter(Context, Android.Resource.Layout.SimpleListItem1, view.ItemsSource);  
    7.         Control.Adapter = adapter;  
    8.     }  
    9.     if (e.PropertyName == Dropdown.SelectedIndexProperty.PropertyName)  
    10.     {  
    11.         Control.SetSelection(view.SelectedIndex);  
    12.     }  
    13.     base.OnElementPropertyChanged(sender, e);  
    14. }  
  1. Add Export Renderer above the namespace to link dropdown view in .NET Standard project to Android Client Project. This is a very important step for any custom renderer approach.
    1. [assembly: ExportRenderer(typeof(Dropdown), typeof(DropdownRenderer))]  
    2. namespace XF.Ctrls.Droid  
Full Code of Dropdown Renderer
 
Here, we will see the full code for Dropdown Renderer.
  1. [assembly: ExportRenderer(typeof(Dropdown), typeof(DropdownRenderer))]  
  2. namespace XF.Ctrls.Droid  
  3. {  
  4.     public class DropdownRenderer : ViewRenderer<Dropdown, Spinner>  
  5.     {  
  6.         Spinner spinner;  
  7.         public DropdownRenderer(Context context) : base(context)  
  8.         {  
  9.   
  10.         }  
  11.   
  12.         protected override void OnElementChanged(ElementChangedEventArgs<Dropdown> e)  
  13.         {  
  14.             base.OnElementChanged(e);  
  15.   
  16.             if (Control == null)  
  17.             {  
  18.                 spinner = new Spinner(Context);  
  19.                 SetNativeControl(spinner);  
  20.             }  
  21.   
  22.             if (e.OldElement != null)  
  23.             {  
  24.                 Control.ItemSelected -= OnItemSelected;  
  25.             }  
  26.             if (e.NewElement != null)  
  27.             {  
  28.                 var view = e.NewElement;  
  29.   
  30.                 ArrayAdapter adapter = new ArrayAdapter(Context, Android.Resource.Layout.SimpleListItem1, view.ItemsSource);  
  31.                 Control.Adapter = adapter;  
  32.   
  33.                 if (view.SelectedIndex != -1)  
  34.                 {  
  35.                     Control.SetSelection(view.SelectedIndex);  
  36.                 }  
  37.   
  38.                 Control.ItemSelected += OnItemSelected;  
  39.             }  
  40.         }  
  41.   
  42.         protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)  
  43.         {  
  44.             var view = Element;  
  45.             if (e.PropertyName == Dropdown.ItemsSourceProperty.PropertyName)  
  46.             {  
  47.                 ArrayAdapter adapter = new ArrayAdapter(Context, Android.Resource.Layout.SimpleListItem1, view.ItemsSource);  
  48.                 Control.Adapter = adapter;  
  49.             }  
  50.             if (e.PropertyName == Dropdown.SelectedIndexProperty.PropertyName)  
  51.             {  
  52.                 Control.SetSelection(view.SelectedIndex);  
  53.             }  
  54.             base.OnElementPropertyChanged(sender, e);  
  55.         }  
  56.   
  57.         private void OnItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)  
  58.         {  
  59.             var view = Element;  
  60.             if (view != null)  
  61.             {  
  62.                 view.SelectedIndex = e.Position;  
  63.                 view.OnItemSelected(e.Position);  
  64.             }  
  65.         }  
  66.     }  
  67. }  

Step 4 - Implementation of Dropdown & Its Demo for Android Platform

 
In this step, we will see how to use a View in Xamarin.Forms.
  1. Open your designer file (in my case, MainPage.xaml) and add the control as shown below.
    1. <local:Dropdown HorizontalOptions="FillAndExpand"  
    2.             VerticalOptions="Center"  
    3.             BackgroundColor="LawnGreen"  
    4.             x:Name="dropdown"/>  
  1. Set ItemsSource and SelectedIndex.
    1. dropdown.ItemsSource = Items1;  
    2. dropdown.SelectedIndex = 1;  
  1. Add item selection event to dropdown.
    1. public MainPage()  
    2. {  
    3.     //...  
    4.     dropdown.ItemSelected += OnDropdownSelected;  
    5. }  
    6.   
    7. private void OnDropdownSelected(object sender, ItemSelectedEventArgs e)  
    8. {  
    9.     label.Text = Items1[e.SelectedIndex];  
    10. }  
Full Code implementation of Dropdown in MainPage
 
Here, we will see the full code for Main Page.
  1. namespace XF.Ctrls  
  2. {  
  3.     public partial class MainPage : ContentPage  
  4.     {  
  5.         List<string> Items1 = new List<string>();  
  6.         List<string> Items2 = new List<string>();  
  7.         bool IsItem1 = true;  
  8.   
  9.         public MainPage()  
  10.         {  
  11.             InitializeComponent();  
  12.   
  13.             for (int i = 0; i < 4; i++)  
  14.             {  
  15.                 Items1.Add(i.ToString());  
  16.             }  
  17.   
  18.             for (int i = 0; i < 10; i++)  
  19.             {  
  20.                 Items2.Add(i.ToString());  
  21.             }  
  22.   
  23.             dropdown.ItemsSource = Items1;  
  24.             dropdown.SelectedIndex = 1;  
  25.             dropdown.ItemSelected += OnDropdownSelected;  
  26.         }  
  27.   
  28.         private void OnDropdownSelected(object sender, ItemSelectedEventArgs e)  
  29.         {  
  30.             label.Text = IsItem1 ? Items1[e.SelectedIndex] : Items2[e.SelectedIndex];  
  31.         }  
  32.   
  33.         private void btn_Clicked(object sender, EventArgs e)  
  34.         {  
  35.             dropdown.ItemsSource = IsItem1 ? Items2 : Items1;  
  36.             dropdown.SelectedIndex = IsItem1 ? 5 : 1;  
  37.             IsItem1 = !IsItem1;  
  38.         }  
  39.     }  
  40. }  

Demo

 
The following screens show the output of this tutorial and it is awesome to have this dropdown in Xamarin.Forms.
 
Dropdown Control In Xamarin.Forms  Dropdown Control In Xamarin.Forms
 
This article covers the implementation of new dropdown control in Android Platform alone. Currently, I am working on creating spinner like dropdown control in iOS platform and will post the article about the implementation of the dropdown in the iOS platform soon.
 
My plan is to create a dropdown control for supporting all platforms and offering this control as a standard plugin.
 

Download Code

 
You can download the full source code from GitHub. If you like this article, do like, share and star the repo in GitHub.