Skip to content

Instantly share code, notes, and snippets.

@Znow
Forked from jessejiang0214/RoundBorderDatePicker.cs
Last active October 8, 2022 09:44
Show Gist options
  • Save Znow/c6bf5c45e0c31289bec596ba93bbb1cc to your computer and use it in GitHub Desktop.
Save Znow/c6bf5c45e0c31289bec596ba93bbb1cc 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. Updated to 2.5 requirements
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;
using Android.Content;
[assembly: ExportRenderer (typeof(RoundBorderDatePicker), typeof(MyApp.Droid.RoundBorderDatePickerRendererDroid))]
namespace MyApp.Droid
{
public class RoundBorderDatePickerRendererDroid : DatePickerRenderer
{
public RounderBorderDatePickerRendererDroid(Context context) : base(context) { }
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