Articles in this section
Category / Section

How to achieve DatePicker using SfPicker in Xamarin Forms

6 mins read

Our Xamarin.Forms Picker control has multi column support. By using this, you can populate date, month, and year values of collection in SfPicker control.

By using Picker control, you can create custom Date Picker.

Step 1: Custom class has been created, and named as “CustomDatePicker”. This class should inherit from SfPicker control.

C#:

 
public class CustomDatePicker : SfPicker
{
 
}
 

 

Step 2: After that, create four ObservableCollection with object type in CustomDatePicker class.

Collection details:

Date Collection, Day Collection, Month Collection, and Year Collection.

Day Collection -> Current month days have been added by using DateTime.DaysInMonth.

Month Collection -> Jan to Dec months have been added.

Year Collection -> 1990 to 2050 years have been added.

Date Collection -> All the three collections have been added.

Date Collection is main collection, which have been assigned it to ItemsSource of Picker Control.

The following code demonstrates Date collection creation.

C#:

public class CustomDatePicker : SfPicker
{
 #region Public Properties
 
 // Months api is used to modify the Day collection as per change in Month
 
 internal Dictionary<string, string> Months { get; set; }
 
 /// <summary>
 /// Date is the acutal DataSource for SfPicker control which will holds the collection of Day ,Month and Year
 /// </summary>
 /// <value>The date.</value>
 public ObservableCollection<object> Date { get; set; }
 
 //Day is the collection of day numbers
 internal ObservableCollection<object> Day { get; set; }
 
 //Month is the collection of Month Names
 internal ObservableCollection<object> Month{ get; set; }
 
 //Year is the collection of Years from 1990 to 2042
 internal ObservableCollection<object> Year{ get; set; }
 
 #endregion
 
 public CustomDatePicker()
 {
  Months = new Dictionary<string, string>();
  Date = new ObservableCollection<object>();
  Day = new ObservableCollection<object>();
  Month = new ObservableCollection<object>();
  Year = new ObservableCollection<object>();
  PopulateDateCollection();
  this.ItemsSource = Date;
 }
 
 
      private void PopulateDateCollection()
  {
 
  //populate months
  for (int i = 1; i < 13; i++)
  {
  if (!Months.ContainsKey(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i).Substring(0, 3)))
     Months.Add(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i).Substring(0, 3), CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i));
    Month.Add(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i).Substring(0, 3));
   }
 
  //populate year
  for (int i = 1990; i < 2050; i++)
  {
   Year.Add(i.ToString());
  }
 
  //populate Days
  for (int i = 1; i <= DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month); i++)
  {
   if (i < 10)
   {
    Day.Add("0" + i);
   }
   else
    Day.Add(i.ToString());
   }
 
   Date.Add(Month);
   Date.Add(Day);
   Date.Add(Year);
  }
 }

 

Step 3: The day value has been updated based on month and year values by using Selection changed event of SfPicker control. Since the days of each month differs, you should handle this collection.

C#:

public CustomDatePicker()
 {
   
         //hook selection changed event
    this.SelectionChanged += CustomDatePicker_SelectionChanged;  
       }
 
private void CustomDatePicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
  UpdateDays(Date, e);
 }
 
//Updatedays method is used to alter the Date collection as per selection change in Month column(if feb is Selected day collection has value from 1 to 28)
 
 public void UpdateDays(ObservableCollection<object> Date, SelectionChangedEventArgs e)
 {
 
 Device.BeginInvokeOnMainThread(() =>
  {
  try
  {
   bool isupdate = false;
   if (e.OldValue != null && e.NewValue != null && (e.OldValue as IList).Count>0 && (e.NewValue as IList).Count>0)
   {
    if ((e.OldValue as IList)[0] != (e.NewValue as IList)[0])
    {
     isupdate = true;
    }
    if ((e.OldValue as IList)[2] != (e.NewValue as IList)[2])
    {
     isupdate = true;
    }
   }
 
   if (isupdate)
   {
   ObservableCollection<object> days = new ObservableCollection<object>();
   int month = DateTime.ParseExact(Months[(e.NewValue as IList)[0].ToString()], "MMMM", CultureInfo.InvariantCulture).Month;
   int year = int.Parse((e.NewValue as IList)[2].ToString());
   for (int j = 1; j <= DateTime.DaysInMonth(year, month); j++)
   {
    if (j < 10)
    {
     days.Add("0" + j);
    }
    else
     days.Add(j.ToString());
   }
 
   if (days.Count > 0)
   {
    Date.RemoveAt(1);
    Date.Insert(1, days);
   }
  }
 
 }
 catch
 {
 
 }
 
});
}
 

 

Step 4: Each column headers such as “Day”, “Month”, and “Year” have been defined by using ColumnHeaderText property of SfPicker control. The following code demonstrates how to define header for each column of SfPicker control.

C#:

public class CustomDatePicker : SfPicker
 {
           /// <summary>
     /// Headers api is holds the column name for every column in date picker
     /// </summary>
     /// <value>The Headers.</value>
     public ObservableCollection<string> Headers { get; set; }
 
           public CustomDatePicker()
  {
   Headers = new ObservableCollection<string>();
   Headers.Add("Month");
   Headers.Add("Day");
   Headers.Add("Year");
 
                     //SfPicker header text
   HeaderText = "Date Picker";
   
                     // Column header text collection
   this.ColumnHeaderText = Headers;
  }
        }

 

Step 5: Finally, SfPicker header, Column header, and footer have been enabled by using ShowHeader, ShowFooter, and ShowColumnHeader properties.

C#:

public CustomDatePicker()
 {
  
  //Enable Footer
   ShowFooter = true;
 
            //Enable SfPicker Header
   ShowHeader = true;
 
            //Enable Column Header of SfPicker
   ShowColumnHeader = true;
 }
 

 

Step 6: CustomDatePicker control has been added in main XAML page. Please refer the following code snippets.

XAML:

 
<ContentPage
    x:Class="DatePicker.DatePickerPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:DatePicker"
    xmlns:picker="clr-namespace:Syncfusion.SfPicker.XForms;assembly=Syncfusion.SfPicker.XForms">
    <ContentPage.BindingContext>
        <local:DatePickerViewModel />
    </ContentPage.BindingContext>
    <Grid>
        <Button
            Clicked="Button_Clicked"
            HeightRequest="30"
            HorizontalOptions="Center"
            Text="Show Picker"
            VerticalOptions="Center"
            WidthRequest="200" />
        <local:CustomDatePicker
            x:Name="date"
            ColumnHeaderHeight="40"
            HorizontalOptions="Center"
            PickerHeight="400"
            PickerMode="Dialog"
            PickerWidth="300"
            SelectedItem="{Binding StartDate}"
            VerticalOptions="Center" />
 
    </Grid>
</ContentPage>
 

 

C#:

 
 public partial class DatePickerPage : ContentPage
    {
        public DatePickerPage()
        {
            InitializeComponent();
        }
 
        private void Button_Clicked(object sender, EventArgs e)
        {
            date.IsOpen = !date.IsOpen;
        }
    }

 

The output has been illustrated in the following screenshot by using the above codes.

 

MultiColumn SfPicker

 

The DatePicker sample has been attached for your reference. Please download the sample from the following link.

 

Sample link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/DatePicker495728461

 

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied