Showing posts with label Xamarin Forms. Show all posts

Placeholder for Picker - Xamarin.Forms

Introduction

In this tutorial, we will learn how to handle the Placeholder issue in Xamarin.Forms for Picker Control. Xamarin.Forms Picker Control is a combination of EditText plus AlertDialog for Android and UITextField plus UIPicker for iOS. The Title property of Xamarin.Forms Picker Control is a property to set title for AlertDialog plus Hint for EditText for Android and Placeholder for UITextField.

For Example, we are setting the title property of the picker control is “Title” and it has items source and selected index of the control as “-1” then the control will shows “Title” in Placeholder and title of the alert or popup. Sometimes, it is meaning less to use this control due to this.

To avoid this issue, I have created a customer render for Android and iOS to override this default behavior of picker. Without much delay, we will skip into the coding part of the article.

Coding Part:

Steps:

I have split the coding part into 5 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Creating Custom Picker inherited from picker.
  3. Custom Renderer for Custom Picker in Android.
  4. Custom Renderer for Custom Picker in iOS.
  5. Implementation of the Custom Picker Control.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Creating Custom Picker inherited from picker

  1. Create a Custom Picker Control class named as “PLPicker” and it is inherited from Xamarin.Forms Picker.
  2. Create a property for Placeholder and is named as Placeholder like below.
    public class PLPicker : Picker
    {
        public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(
            propertyName: nameof(Placeholder),
            returnType: typeof(string),
            declaringType: typeof(string),
            defaultValue: string.Empty);
    
        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }
    
    }

Step 3: Custom Renderer for Custom Picker in Android

In this step, we will create a custom renderer in Android for PLPicker created in “Step 2”.

  1. Create a class named as “PLPickerRenderer.cs” and it is inherited from “Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer”.
  2. Then create a method “UpdatePickerPlaceholder” and copy the below code in the custom renderer class.
    void UpdatePickerPlaceholder()
    {
        if (picker == null)
            picker = Element as PLPicker;
        if (picker.Placeholder != null)
            Control.Hint = picker.Placeholder;
    }
  3. Call this method, in the OnElementChanged method and OnElementPropertyChanged method when the placeholder property changes.
  4. You can find the full coding part for “PLPickerRenderer.cs” below for Android.
    [assembly: ExportRenderer(typeof(PLPicker), typeof(PLPickerRenderer))]
    namespace PickerPlaceholder.Droid
    {
        public class PLPickerRenderer : Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
        {
            PLPicker picker = null;
            public PLPickerRenderer(Context context) : base(context)
            {
    
            }
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    picker = Element as PLPicker;
                    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(PLPicker.PlaceholderProperty.PropertyName))
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
    
            protected override void UpdatePlaceHolderText()
            {
                UpdatePickerPlaceholder();
            }
    
            void UpdatePickerPlaceholder()
            {
                if (picker == null)
                    picker = Element as PLPicker;
                if (picker.Placeholder != null)
                    Control.Hint = picker.Placeholder;
            }
        }
    }

Step 4: Custom Renderer for Custom Picker in iOS

In this step, we will create a custom renderer in iOS for PLPicker created in “Step 2”.

  1. Create a class named as “PLPickerRenderer.cs” and it is inherited from “Xamarin.Forms.Platform.iOS.PickerRenderer”.
  2. Then create a method “UpdatePickerPlaceholder” and copy the below code in the custom renderer class.
    void UpdatePickerPlaceholder()
    {
        if (picker == null)
            picker = Element as PLPicker;
        if (picker.Placeholder != null)
            Control.Placeholder = picker.Placeholder;
    }
  3. Call this method, in the OnElementChanged method and OnElementPropertyChanged method when the placeholder property changes.
  4. You can find the full coding part for “PLPickerRenderer.cs” below for Android.
    [assembly: ExportRenderer(typeof(PLPicker), typeof(PLPickerRenderer))]
    namespace PickerPlaceholder.iOS
    {
        public class PLPickerRenderer: PickerRenderer
        {
            PLPicker picker = null;
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    picker = Element as PLPicker;
                    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(PLPicker.PlaceholderProperty.PropertyName))
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
    
            void UpdatePickerPlaceholder()
            {
                if (picker == null)
                    picker = Element as PLPicker;
                if (picker.Placeholder != null)
                    Control.Placeholder = picker.Placeholder;
            }
        }
    }

Step 5: Implementation of Custom Picker Control

In this step, we will create a custom renderer in iOS for PLPicker created in “Step 2”.

  1. Open created Xamarin.Forms Page, in my case “MainPage” and add the custom control picker with Placeholder property.
  2. Open your MainPage.xaml file and add the custom control as shown in below.
    <local:PLPicker Placeholder="Placeholder"
                    Title="Title"
                    TitleColor="Blue"
                    x:Name="plpicker"
                    Grid.Row="2"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"/>
  3. Then add buttons with clicked events to change selected index as 1 and -1 for the custom picker.
    <Button Text="PLPicker:Set Index 1"
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Clicked="PLPIndex1Clicked"
            Grid.Row="3"
            Grid.Column="0"/>
    
    <Button Text="PLPicker:Set Index -1"
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Clicked="PLPIndex2Clicked"
            Grid.Row="3"
            Grid.Column="1" />
  4. Create an event for setting the selected index for picker as like below.
    private void PLPIndex1Clicked(object sender, EventArgs e)
    {
        plpicker.SelectedIndex = 1;
    }
    
    private void PLPIndex2Clicked(object sender, EventArgs e)
    {
        plpicker.SelectedIndex = -1;
    }

Output:

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Calendarview in Xamarin.Forms


Introduction

In this tutorial, we will learn how to use Calendarview in Xamarin.Forms. This plugin will helps more when we creating a mobile app for attendance management system.
This Calendar Control is an awesome plugin created by Rebecca and is open sourced in GitHub.
This control offers

  1. Single date selection,
  2. Multi date selection,
  3. Special date selection and date background selection as image and background pattern.

To know more about we will skip into the coding part without delay.

Coding Part:

Steps:

I have split this part into 3 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Setting up the plugin for Xamarin.Forms
  3. Implementing Calendar View in Xamarin.Forms.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Setting up the plugin for Xamarin.Forms

  1. Open Nuget Package Manager against the solution and do search for Calendar Control Plugin.
  2. Click Install to install this Plugin against your PCL Project or .NET standard Project.
  3. We need to install this plugin in all client projects.

Step 3: Implementing Calendarview in Xamarin.Forms

  1. After installing the plugin into the project, open your designer page (in my case “MainPage.xaml”) and add the following line for importing the calendar control.
    xmlns:controls="clr-namespace:XamForms.Controls;assembly=XamForms.Controls.Calendar"
  2. Then add the calendar control in your page like below
    <controls:Calendar Padding="10,0,10,0" 
                       SelectedBorderWidth="4" 
                       DisabledBorderColor="Black"
                       ShowNumberOfWeek="false"
                       StartDay="Monday"
                       TitleLabelTextColor="Purple"
                       TitleLeftArrowTextColor="Blue"
                       SelectedDate="{Binding Date}"
                       SpecialDates="{Binding Attendances}"
                       DateCommand="{Binding DateChosen}"/>
  3. Here, SelectedDate is used to select date by default, SpecialDates is used to highlight the sepecial dates like "Holidays", "Festivals", "Appointments" and more.
  4. In this project, we are using MVVM pattern. So, we should create a page model and add this to binding context. After that, add bindable properties for SelectedDate, SpecialDates.
  5. Selection of a particular date can be identified by the "DateCommand". Below you can find the whole code implementations of the PageModel.
    namespace CalendarSample
    {
        public class MainPageModel : BindableObject
        {
            private DateTime? _date;
            public DateTime? Date
            {
                get
                {
                    return _date;
                }
                set
                {
                    _date = value;
                    OnPropertyChanged(nameof(Date));
                }
            }
    
            private ObservableCollection attendances;
            public ObservableCollection Attendances
            {
                get
                {
                    return attendances;
                }
                set
                {
                    attendances = value;
                    OnPropertyChanged(nameof(Attendances));
                }
            }
    
            public Command DateChosen
            {
                get
                {
                    return new Command((obj) =>
                    {
                        System.Diagnostics.Debug.WriteLine(obj as DateTime?);
                    });
                }
            }
        }
    }
  6. You can find the output of this application below

Full Code:

MainPage.xaml

<?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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:controls="clr-namespace:XamForms.Controls;assembly=XamForms.Controls.Calendar"
             xmlns:viewmodels="clr-namespace:CalendarSample"
             mc:Ignorable="d"
             x:DataType="viewmodels:MainPageModel"
             x:Class="CalendarSample.MainPage">

    <StackLayout>
        <controls:Calendar Padding="10,0,10,0" 
                           SelectedBorderWidth="4" 
                           DisabledBorderColor="Black"
                           ShowNumberOfWeek="false"
                           StartDay="Monday"
                           TitleLabelTextColor="Purple"
                           TitleLeftArrowTextColor="Blue"
                           SelectedDate="{Binding Date}"
                           SpecialDates="{Binding Attendances}"
                           DateCommand="{Binding DateChosen}"/>
    </StackLayout>

</ContentPage>

MainPageModel.cs

using System;
using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace CalendarSample
{
    public class MainPageModel : BindableObject
    {
        private DateTime? _date;
        public DateTime? Date
        {
            get
            {
                return _date;
            }
            set
            {
                _date = value;
                OnPropertyChanged(nameof(Date));
            }
        }

        private ObservableCollection attendances;
        public ObservableCollection Attendances
        {
            get
            {
                return attendances;
            }
            set
            {
                attendances = value;
                OnPropertyChanged(nameof(Attendances));
            }
        }

        public Command DateChosen
        {
            get
            {
                return new Command((obj) =>
                {
                    System.Diagnostics.Debug.WriteLine(obj as DateTime?);
                });
            }
        }
    }
}

Reference

Calendar Control in Xamarin.Formshttps://github.com/rebeccaXam/XamForms.Controls.Calendar

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.