Introduction
This article describes how we can set 24h format for TimePicker Control. Sometimes we may get the requirement to set 24h for TimePicker, So in this article, we can learn how to achieve this functionality using CustomRenderer.
Requirements:
- This article source code is prepared by using Visual Studio. And it is better to install latest visual studio updates from here.
- This article is prepared on a MAC machine.
- This sample project is Xamarin.Forms PCL project.
- This sample app is targeted for Android, iOS. And tested for Android & iOS.
Description:
The creation of Xamarin.Forms project is very simple in Visual Studio for Mac. It creates will three projects
1) Shared Code
2) Xamarin.Android
3) Xamarin.iOS
Because Mac system with Visual Studio for Mac it doesn't support Windows projects(UWP, Windows, Windows Phone)
First, open the Visual Studio for Mac. And Click on New Project
Then we have to give the App Name i.e TimePickerDemo.
Note: In the above screen under Shared Code, select Portable class Library or Use Shared Library.
Then click on Next Button the following screenshot will be displayed. In that screen, we have to browse the file path where we want to save that application on our PC.
After Click on Create, button it will create the RoundedCornerViewDemo Xamarin.Forms project like below.
And project structure will be.
- TimePickerDemo: It is for Shared Code
- TimePickerDemo.Droid: It is for Android.
- TimePickerDemo.iOS: It is for iOS
We need to follow below few steps to set 24H for TimePicker.
Portable Class Library (PCL):
Step 1:
In PCL, create a class name is CustomTimePicker24H which should inherit any TimePicker like below.
Step 2:
In PCL, create a class name is CustomTimePicker24H which should inherit any TimePicker like below.
CustomTimePicker24H.cs
- using System;
- using Xamarin.Forms;
- namespace TimePickerDemo
- {
- public class CustomTimePicker24H : TimePicker
- {
- public CustomTimePicker24H()
- {
- }
- }
- }
Step 2:
Create your own Xaml page name is TimePicker24HPage.xaml, and make sure refer "CustomTimePicker24H" class in Xaml by declaring a namespace for its location and using the namespace prefix on the control element. The following code example shows how the "CustomTimePicker24H" renderer class can be consumed by a Xaml page:
TimePicker24HPage.xaml
- <?xml version="1.0" encoding="UTF-8"?>
- <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" BackgroundColor="White" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:custom="clr-namespace:TimePickerDemo.CustomControls;assembly=TimePickerDemo" x:Class="TimePickerDemo.Views.TimePicker24HPage">
- <ContentPage.Content>
- <StackLayout Padding="30,80,30,0" Spacing="40" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
- <Label Text="TimePicker 24H Format" HorizontalOptions="CenterAndExpand" TextColor="Gray" FontSize="20"/>
- <custom:CustomTimePicker24H TextColor="Gray" Format="HH:mm" HeightRequest="40" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"/>
- </StackLayout>
- </ContentPage.Content>
- </ContentPage>
Note:
The "custom" namespace prefix can be named anything. However, the clr-namespace and assembly values must match the details of the custom renderer class. Once the namespace is declared the prefix is used to reference the custom control.
TimePicker24HPage.xaml.cs
- using System;
- using System.Collections.Generic;
- using Xamarin.Forms;
- namespace TimePickerDemo.Views
- {
- public partial class TimePicker24HPage : ContentPage
- {
- public TimePicker24HPage()
- {
- InitializeComponent();
- }
- }
- }
Xamarin.Andriod:
In Android project, create a class name is CustomTimePicker24HRenderer and make sure to add renderer registration for our CustomTimePicker24H class in above of the namespace:
CustomTimePicker24HRenderer.cs
- using System;
- using Android.Widget;
- using Xamarin.Forms;
- using Xamarin.Forms.Platform.Android;
- using Android.App;
- using Android.Runtime;
- using TimePickerDemo.Droid;
- using TimePickerDemo.CustomControls;
- [assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
- namespace TimePickerDemo.Droid
- {
- public class CustomTimePicker24HRenderer : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
- {
- private TimePickerDialog dialog = null;
- protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
- {
- base.OnElementChanged(e);
- this.SetNativeControl(new Android.Widget.EditText(Forms.Context));
- this.Control.Click += Control_Click;
- this.Control.Text = DateTime.Now.ToString("HH:mm");
- this.Control.KeyListener = null;
- this.Control.FocusChange += Control_FocusChange;
- }
- void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
- {
- if (e.HasFocus)
- ShowTimePicker();
- }
- void Control_Click(object sender, EventArgs e)
- {
- ShowTimePicker();
- }
- private void ShowTimePicker()
- {
- if (dialog == null)
- {
- dialog = new TimePickerDialog(Forms.Context, this, DateTime.Now.Hour, DateTime.Now.Minute, true);
- }
- dialog.Show();
- }
- public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
- {
- var time = new TimeSpan(hourOfDay, minute, 0);
- this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);
- this.Control.Text = time.ToString(@"hh\:mm");
- }
- }
- }
Here OnElementChanged method instantiates an Android UI Layout in that I assigned current time to TimePicker and set 24h format.
Xamarin.iOS
In iOS project, create a class name is CustomTimePicker24HRenderer and make sure to add renderer registration for our CustomTimePicker24H class in above of the namespace:
In iOS project, create a class name is CustomTimePicker24HRenderer and make sure to add renderer registration for our CustomTimePicker24H class in above of the namespace:
CustomTimePicker24HRenderer.cs
- using System;
- using Xamarin.Forms.Platform.iOS;
- using UIKit;
- using Xamarin.Forms;
- using TimePickerDemo.iOS;
- using Foundation;
- using TimePickerDemo.CustomControls;
- [assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
- namespace TimePickerDemo.iOS
- {
- public class CustomTimePicker24HRenderer : TimePickerRenderer
- {
- protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
- {
- base.OnElementChanged(e);
- var timePicker = (UIDatePicker)Control.InputView;
- timePicker.Locale = new NSLocale("no_nb");
- if (Control != null)
- {
- Control.Text = DateTime.Now.ToString("HH:mm");
- }
- }
- }
- }
Here OnElementChanged method instantiates a Here OnElementChanged method instantiates an iOS UI, in that I assigned current time to the Control and set 24h format using NSLocale.
The property changed event is not fired when the date is not change and ok is clicked , which is expected. But the Unfocused event is also fired when Ok / Cancel is pressed on Android .
ReplyDelete