Placeholder or Picker in Xamarin.Forms

Xamarin has become the primary choice when it comes to building apps from a single shared codebase. Xamarin would help you with increasing global customers just by mastering Multilingual in Xamarin.Forms. Here, in this blog, we will discuss the concept of Placeholder for Picker in Xamarin.Forms.

Picker is a control used to select items from the list of data. It works like a drop-down list. Picker is a combination of EditText and AlertDialog for Android.

Picker control contains various properties like Title, ItemsSource, SelectedIndex, SelectedItem, etc. The Title property set the title for AlertDialog and Hint for EditText. When we set title property to control it will show the title in a placeholder, sometime there is no meaning to use the control because of this. To avoid this problem and handle placeholder issues in Picker control we will be going to create a custom renderer for Picker (For Android).

Steps for Creating custom Renderer:

  • Create new Xamarin.Forms Project and give an appropriate name to the Application.
  • Create one folder in a shared project for Renderer and create one class for a custom renderer.
  • Inherit Picker to this class and create a property for Picker.
  • After this create a class in the Android platform. In this class, we will create a custom renderer in android for the class which we have created in the Shared project’s folder for Picker.
  • Now we will implement custom Picker control in the XAML file.

Custom renderer class for Picker:

using Xamarin.Forms;

namespace PlaceholderForPicker.Renderers

{

    public class PlaceholderPicker:Picker

    {

        public static readonly BindableProperty placeholderbindableProperty = BindableProperty.Create (

            propertyName:nameof( Placeholder ),

            returnType:typeof(string),

            declaringType:typeof(string),

            defaultValue:string.Empty

            ) ;

        public string Placeholder

        {

            get{ return (string) GetValue (placeholderbindableProperty) ; }

            set { SetValue( placeholderbindableProperty, value ); }

        }

    }

}

As above mention, we have created a class for custom renderer and name it as PlaceholderPicker. After that, we have inherited Picker control and created Property for Placeholder and name it as Placeholder.

Custom renderer class for Picker inside Android:

using System;

using System.ComponentModel;

using Android.Content;

using PlaceholderForPicker.Droid;

using PlaceholderForPicker.Renderers;

using Xamarin.Forms;

using Xamarin.Forms.Platform.Android;

#pragma warning disable CS0612

See also  The Five Most Common HTTP Errors

[assembly:ExportRenderer(typeof(PlaceholderPicker), typeof(PlaceholderPickerRenderer))]

#pragma warning restore CS0612

namespace PlaceholderForPicker.Droid

{

    [Obsolete]

    public class PlaceholderPickerRenderer:PickerRenderer

    {

        PlaceholderPicker ppicker= null;

        public PlaceholderPickerRenderer(Context context) : base(context)

        {

        }

        protected override void OnElementChanged( ElementChangedEventArgs<Picker> e)

        {

            base.OnElementChanged( e );

            if ( e.NewElement != null )

            {

                ppicker = Element as PlaceholderPicker;

                UpdatepickerPlaceholder();

                if ( ppicker.SelectedIndex <= -1 )

                {

                    UpdatepickerPlaceholder();

                }

            }

        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)

        {

            base.OnElementPropertyChanged(sender, e);

            if ( ppicker != null )

            {

                if (e.PropertyName.Equals(PlaceholderPicker.placeholderbindableProperty.PropertyName ) )

                {

                    UpdatepickerPlaceholder();

                }

            }

        }

        void UpdatepickerPlaceholder()

        {

           if( ppicker == null )

            {

                ppicker = Element as PlaceholderPicker;

            }

            if( ppicker.Placeholder != null )

            {

                Control.Hint = ppicker.Placeholder;

            }

        }

    }

}

The above code is for PlaceholderPickerRenderer class which is created inside android. We have inherited PickerRenderer and created methods UpdatepickerPlaceholder, OnElementChanged and OnElementPropertyChanged (). We will call UpdatepickerPlaceholder method into those last two methods. We will call those two methods when a property of Placeholder will change and add assembly above the namespace.

The same way we can do for iOS, mentioned below is for custom renderer in iOS for custom Picker. We have done the same things as we have done in PlaceholderPickerRenderor in Android.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Linq;

using System.Text;

using Foundation;

using PlaceholderForPicker.iOS;

using PlaceholderForPicker.Renderers;

using UIKit;

using Xamarin.Forms;

using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(PlaceholderPicker), typeof(PlaceholderPickerRendererios))]

namespace PlaceholderForPicker.iOS

{

   public class PlaceholderPickerRendererios:PickerRenderer

    {

        PlaceholderPicker picker = null;

        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)

        {

            base.OnElementChanged(e);

            if (e.NewElement != null)

            {

                picker = Element as PlaceholderPicker;

                UpdatepickerPlaceholder();

                if (picker.SelectedIndex <= -1)

                {

                    UpdatepickerPlaceholder();

                }

            }

        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)

        {

            base.OnElementPropertyChanged(sender, e);

            if (picker != null)

            {

                if (e.PropertyName.Equals(PlaceholderPicker.placeholderbindableProperty.PropertyName))

                {

                    UpdatepickerPlaceholder();

                }

            }

        }

        void UpdatepickerPlaceholder()

        {

            if (picker == null)

                picker = Element as PlaceholderPicker;

            if (picker.Placeholder != null)

                Control.Placeholder = picker.Placeholder;

        }

    }

}

Implementing Custom Picker:

<?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:local=”clr-namespace:PlaceholderForPicker.Renderers”

             x:Class=”PlaceholderForPicker.MainPage”>

    <StackLayout>

        <Picker Title = “City”

                    x:Name = “picker”

                   />

        <local:PlaceholderPicker

            Placeholder=”Select City”

                            Title = “City”

                            TitleColor  =”Black”

                            x:Name = “pplpicker”>

        </local:PlaceholderPicker>

    </StackLayout>

</ContentPage>

In the above code, we have implemented a custom picker for that we have added namespace and used <local: PlaceholderPicker> </local: PlaceholderPicker > we have also created another simple or we can say default Picker control.

See also  How to fix Poor Page Load Speed

In custom picker control, we have used Placeholder property which we have created in PlaceholderPicker class and title property. And in default Picker control we have used only title property.

Code behind of XAML page:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Xamarin.Forms;

namespace PlaceholderForPicker

{

    public partial class MainPage : ContentPage

    {

        public MainPage()

        {

            InitializeComponent();

            List<string> items = new List<string>();

            items.Add (“Surat”);

            items.Add (“Baroda”);

            items.Add (“Rajkot”);

            items.Add (“Surendranagar”);

            picker.ItemsSource =  items;

            pplpicker.ItemsSource =  items;

        }

    }

}

Here, we have created a list to add items in ItemSource for both Picker.

Image: Main page

Image: Default Picker

Image: Picker Created using Custom Renderer

In the above example, we have created Picker with Placeholder. For that we have created a custom renderer for picker then inside renderer class we have inherited Picker control and create a property for Placeholder. After creating a custom renderer, we have created one class in both the android and iOS platforms and inherit PickerRenderer. And apply logic inside those classes. At last, we have implemented a custom Picker into our XAML file. As we have two pickers in our XAML file we can see in output in default Picker control Title shows as a placeholder and when we select picker it is set to the Title of AlertDialog box and for another picker created using custom renderer placeholder and Title both are set with a different value. In this way, we can solve the issue of placeholder of Picker in xamarin forms.

Conclusion:

In the above blog, we have created a simple application with two Picker control to solve the issue of Placeholder of Picker in Xamarin.Forms. The problem with picker control is when we set title property it will work as a placeholder and when we select picker control it will work as a title. To solve this issue, we have use renderer in our application and created a custom Picker where we have set a property for placeholder and use it in a renderer.

Author Bio: Vinod Satapara – Technical Director, iFour Technolab Netherlands Technocrat and entrepreneur with years of experience building large scale enterprise web, cloud and mobile applications using latest technologies like ASP.NET, CORE, .NET MVC, Angular and Blockchain. Keen interest in addressing business problems using latest technologies and have been associated with Mobile Application development companies.
Vinod Satapara

We will be happy to hear your thoughts

Leave a reply

Logo