Skip to content

Instantly share code, notes, and snippets.

@jessejiang0214
Last active October 8, 2022 09:42
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jessejiang0214/9008eed1c6d814159b65 to your computer and use it in GitHub Desktop.
Save jessejiang0214/9008eed1c6d814159b65 to your computer and use it in GitHub Desktop.
This is the Xamarin Forms date picker extension. It can set border width, color and radius, also it can add PlaceHolder and MinimumAge
using System;
using Xamarin.Forms;
namespace MyApp
{
public interface ICanBeValidated
{
Action<bool> ValidateChange { get; set; }
bool IsValidated { get; set; }
Xamarin.Forms.Color BorderColor { get; set; }
double BorderWidth { get; set; }
double BorderRadius { get; set; }
}
public class RoundBorderDatePicker : DatePicker, ICanBeValidated
{
public RoundBorderDatePicker ()
{
// It seems that all the picker need to validated
IsValidated = false;
BorderColor = Color.Red;
this.DateSelected += RoundBorderDatePicker_DateSelected;
}
public static readonly BindableProperty BorderWidthProperty = BindableProperty.Create (
"BorderWidth",
typeof(double),
typeof(RoundBorderDatePicker),
2.0);
public double BorderWidth {
get {
return (double)GetValue (BorderWidthProperty);
}
set {
SetValue (BorderWidthProperty, value);
}
}
public static readonly BindableProperty BorderColorProperty = BindableProperty.Create (
"BorderColor",
typeof(Color),
typeof(RoundBorderDatePicker),
Color.FromHex ("#807A79"));
public Color BorderColor {
get {
return (Color)GetValue (BorderColorProperty);
}
set {
SetValue (BorderColorProperty, value);
}
}
public static readonly BindableProperty BorderRadiusProperty = BindableProperty.Create (
"BorderRadius",
typeof(double),
typeof(RoundBorderDatePicker),
20.0);
public double BorderRadius {
get {
return (double)GetValue (BorderRadiusProperty);
}
set {
SetValue (BorderRadiusProperty, value);
}
}
public static readonly BindableProperty PlaceHolderProperty = BindableProperty.Create (
"PlaceHolder",
typeof(string),
typeof(RoundBorderDatePicker),
"");
public string PlaceHolder {
get {
return (string)GetValue (PlaceHolderProperty);
}
set {
SetValue (PlaceHolderProperty, value);
}
}
public static readonly BindableProperty MinimumAgeProperty = BindableProperty.Create (
"MinimumAge",
typeof(int),
typeof(RoundBorderDatePicker),
18);
public int MinimumAge {
get {
return (int)GetValue (MinimumAgeProperty);
}
set {
SetValue (MinimumAgeProperty, value);
}
}
public Action<bool> ValidateChange { get; set; }
public bool IsValidated { get; set; }
void RoundBorderDatePicker_DateSelected (object sender, DateChangedEventArgs e)
{
if (e.NewDate.Date != DateTime.Now.Date && e.NewDate.Year < (DateTime.Now.Year - MinimumAge)) {
IsValidated = true;
if (ValidateChange != null)
ValidateChange (true);
BorderColor = Color.FromHex ("#807A79");
} else {
IsValidated = false;
if (ValidateChange != null)
ValidateChange (false);
BorderColor = Color.Red;
}
}
}
}
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer (typeof(RoundBorderDatePicker), typeof(MyApp.Droid.RoundBorderDatePickerRendererDroid))]
namespace MyApp.Droid
{
public class RoundBorderDatePickerRendererDroid : DatePickerRenderer
{
RoundBorderHelper _helper;
protected override void OnElementChanged (ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged (e);
if (Control != null && Element is ICanBeValidated)
_helper = new RoundBorderHelper (Control, Element as ICanBeValidated);
Control.Text = (Element as RoundBorderDatePicker).PlaceHolder;
(Element as ICanBeValidated).ValidateChange = (obj) => {
if(!obj)
Control.Text = (Element as RoundBorderDatePicker).PlaceHolder;
};
}
protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged (sender, e);
_helper.UpdateBorderByPropertyName (e.PropertyName);
}
}
}
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer (typeof(RoundBorderDatePicker), typeof(MyApp.iOS.RoundBorderDatePickerRendereriOS))]
namespace MyApp.iOS
{
public class RoundBorderDatePickerRendereriOS : DatePickerRenderer
{
RoundBorderHelper _helper;
protected override void OnElementChanged (ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged (e);
if (Control != null && Element is ICanBeValidated) {
_helper = new RoundBorderHelper (Control, Element as ICanBeValidated);
Control.Text = (Element as RoundBorderDatePicker).PlaceHolder;
(Element as ICanBeValidated).ValidateChange = (obj) => {
if(!obj)
Control.Text = (Element as RoundBorderDatePicker).PlaceHolder;
};
}
}
protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged (sender, e);
_helper.UpdateBorderByPropertyName (e.PropertyName);
}
}
}
using System;
using Android.Views;
using Android.Graphics.Drawables;
using Xamarin.Forms.Platform.Android;
namespace MyAPP.Droid
{
public class RoundBorderHelper
{
View _control;
ICanBeValidated _element;
public RoundBorderHelper (View control, ICanBeValidated element)
{
_control = control;
_element = element;
UpdateBorder ();
}
public void UpdateBorder ()
{
GradientDrawable gd = new GradientDrawable ();
//gd.SetColor (_element.BackgroundColor.ToAndroid ());
gd.SetStroke ((int)_element.BorderWidth * 2, _element.BorderColor.ToAndroid ());
gd.SetCornerRadius ((float)_element.BorderRadius);
_control.SetBackground (gd);
}
public void UpdateBorderByPropertyName (string propertyName)
{
switch (propertyName) {
case "BorderColor":
case "BorderRadius":
case "BorderWidth":
UpdateBorder ();
break;
default:
return;
}
}
}
}
using System;
using UIKit;
using Xamarin.Forms.Platform.iOS;
namespace MyApp.iOS
{
public class RoundBorderHelper
{
UITextField _control;
ICanBeValidated _element;
public RoundBorderHelper (UITextField control, ICanBeValidated element)
{
_control = control;
_element = element;
_control.BorderStyle = UITextBorderStyle.RoundedRect;
_control.ClipsToBounds = true;
_control.Layer.MasksToBounds = true;
UpdateBorder ();
}
public void UpdateBorder ()
{
_control.Layer.CornerRadius = (nfloat)_element.BorderRadius;
_control.Layer.BorderColor = _element.BorderColor.ToCGColor ();
_control.Layer.BorderWidth = (nfloat)_element.BorderWidth;
}
public void UpdateBorderByPropertyName (string propertyName)
{
switch (propertyName) {
case "BorderColor":
case "BorderRadius":
case "BorderWidth":
UpdateBorder ();
break;
default:
return;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment