Last active
May 29, 2021 16:08
-
-
Save farukaf/3f5f1891f27963f828d223cd498d9538 to your computer and use it in GitHub Desktop.
Nullable DatePicker Xamarin - Update from jrgcubano
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using Xamarin.Forms; | |
namespace NullableDateAPP.Controls | |
{ | |
public class NullableDatePicker : DatePicker | |
{ | |
public NullableDatePicker() : base() | |
{ | |
} | |
/// <summary> | |
/// The font property | |
/// </summary> | |
public static readonly BindableProperty FontProperty = | |
BindableProperty.Create("Font", typeof(Font), typeof(NullableDatePicker), new Font()); | |
/// <summary> | |
/// The NullableDate property | |
/// </summary> | |
public static readonly BindableProperty NullableDateProperty = | |
BindableProperty.Create("NullableDate", typeof(DateTime?), typeof(NullableDatePicker), null, BindingMode.TwoWay); | |
/// <summary> | |
/// The XAlign property | |
/// </summary> | |
public static readonly BindableProperty XAlignProperty = | |
BindableProperty.Create("XAlign", typeof(TextAlignment), typeof(NullableDatePicker), | |
TextAlignment.Start); | |
/// <summary> | |
/// The HasBorder property | |
/// </summary> | |
public static readonly BindableProperty HasBorderProperty = | |
BindableProperty.Create("HasBorder", typeof(bool), typeof(NullableDatePicker), true); | |
/// <summary> | |
/// The Placeholder property | |
/// </summary> | |
public static readonly BindableProperty PlaceholderProperty = | |
BindableProperty.Create("Placeholder", typeof(string), typeof(NullableDatePicker), string.Empty, BindingMode.OneWay); | |
/// <summary> | |
/// The PlaceholderTextColor property | |
/// </summary> | |
public static readonly BindableProperty PlaceholderTextColorProperty = | |
BindableProperty.Create("PlaceholderTextColor", typeof(Color), typeof(NullableDatePicker), Color.Default); | |
/// <summary> | |
/// Gets or sets the Font | |
/// </summary> | |
public Font Font | |
{ | |
get { return (Font)GetValue(FontProperty); } | |
set { SetValue(FontProperty, value); } | |
} | |
/// <summary> | |
/// Get or sets the NullableDate | |
/// </summary> | |
public DateTime? NullableDate | |
{ | |
get { return (DateTime?)GetValue(NullableDateProperty); } | |
set | |
{ | |
if (value != NullableDate) | |
{ | |
SetValue(NullableDateProperty, value); | |
UpdateDate(); | |
} | |
} | |
} | |
/// <summary> | |
/// Gets or sets the X alignment of the text | |
/// </summary> | |
public TextAlignment XAlign | |
{ | |
get { return (TextAlignment)GetValue(XAlignProperty); } | |
set { SetValue(XAlignProperty, value); } | |
} | |
/// <summary> | |
/// Gets or sets if the border should be shown or not | |
/// </summary> | |
public bool HasBorder | |
{ | |
get { return (bool)GetValue(HasBorderProperty); } | |
set { SetValue(HasBorderProperty, value); } | |
} | |
/// <summary> | |
/// Get or sets the PlaceHolder | |
/// </summary> | |
public string Placeholder | |
{ | |
get { return (string)GetValue(PlaceholderProperty); } | |
set { SetValue(PlaceholderProperty, value); } | |
} | |
/// <summary> | |
/// Sets color for placeholder text | |
/// </summary> | |
public Color PlaceholderTextColor | |
{ | |
get { return (Color)GetValue(PlaceholderTextColorProperty); } | |
set { SetValue(PlaceholderTextColorProperty, value); } | |
} | |
protected override void OnBindingContextChanged() | |
{ | |
base.OnBindingContextChanged(); | |
UpdateDate(); | |
} | |
protected override void OnPropertyChanged(string propertyName = null) | |
{ | |
base.OnPropertyChanged(propertyName); | |
if (propertyName == DateProperty.PropertyName) | |
{ | |
NullableDate = Date; | |
} | |
if (propertyName == NullableDateProperty.PropertyName) | |
{ | |
if (NullableDate.HasValue) | |
{ | |
Date = NullableDate.Value; | |
OnPropertyChanged(DateProperty.PropertyName); | |
} | |
} | |
} | |
private void UpdateDate() | |
{ | |
if (NullableDate.HasValue) | |
{ | |
Date = NullableDate.Value; | |
} | |
else | |
{ | |
Date = DateTime.Today; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UIKit; | |
using Xamarin.Forms; | |
namespace NullableDateAPP.iOS.Extensions | |
{ | |
/// <summary> | |
/// Color extensions | |
/// </summary> | |
public static class CheckColorExtensions | |
{ | |
internal static readonly UIColor SeventyPercentGrey = new UIColor(0.7f, 0.7f, 0.7f, 1); | |
public static bool IsDefault(this Color color) => Color.Default == color; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Android.Views; | |
using System.ComponentModel; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.Android; | |
using NullableDateAPP.Droid.Renderer; | |
using Android.Content; | |
using NullableDateAPP.Controls; | |
using System; | |
using Android.App; | |
using System.Globalization; | |
[assembly: ExportRenderer(typeof(NullableDatePicker), typeof(NullableDatePickerRenderer))] | |
namespace NullableDateAPP.Droid.Renderer | |
{ | |
public class NullableDatePickerRenderer : DatePickerRenderer | |
{ | |
public NullableDatePickerRenderer(Context context): base(context) | |
{ | |
} | |
protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day) | |
{ | |
var dialog = base.CreateDatePickerDialog(year, month, day); | |
//capture OK click | |
dialog.DateSet += Dialog_DateSet; | |
return dialog; | |
} | |
private void Dialog_DateSet(object sender, DatePickerDialog.DateSetEventArgs e) | |
{ | |
var view = (NullableDatePicker)Element; | |
view.NullableDate = view.Date; | |
} | |
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e) | |
{ | |
base.OnElementChanged(e); | |
//Remove line under input | |
Control?.SetBackgroundColor(Android.Graphics.Color.Transparent); | |
var view = Element as NullableDatePicker; | |
if (view != null) | |
{ | |
SetFont(view); | |
SetTextAlignment(view); | |
// SetBorder(view); | |
SetNullableText(view); | |
SetPlaceholder(view); | |
SetPlaceholderTextColor(view); | |
} | |
} | |
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) | |
{ | |
base.OnElementPropertyChanged(sender, e); | |
var view = (NullableDatePicker)Element; | |
if (e.PropertyName == NullableDatePicker.FontProperty.PropertyName) | |
SetFont(view); | |
else if (e.PropertyName == NullableDatePicker.XAlignProperty.PropertyName) | |
SetTextAlignment(view); | |
// else if (e.PropertyName == NullableDatePicker.HasBorderProperty.PropertyName) | |
// SetBorder(view); | |
else if (e.PropertyName == NullableDatePicker.NullableDateProperty.PropertyName) | |
SetNullableText(view); | |
else if (e.PropertyName == NullableDatePicker.PlaceholderProperty.PropertyName) | |
SetPlaceholder(view); | |
else if (e.PropertyName == NullableDatePicker.PlaceholderTextColorProperty.PropertyName) | |
SetPlaceholderTextColor(view); | |
} | |
/// <summary> | |
/// Sets the text alignment. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetTextAlignment(NullableDatePicker view) | |
{ | |
switch (view.XAlign) | |
{ | |
case Xamarin.Forms.TextAlignment.Center: | |
Control.Gravity = GravityFlags.CenterHorizontal; | |
break; | |
case Xamarin.Forms.TextAlignment.End: | |
Control.Gravity = GravityFlags.End; | |
break; | |
case Xamarin.Forms.TextAlignment.Start: | |
Control.Gravity = GravityFlags.Start; | |
break; | |
} | |
} | |
/// <summary> | |
/// Sets the font. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetFont(NullableDatePicker view) | |
{ | |
if (view.Font != Font.Default) | |
{ | |
Control.TextSize = view.Font.ToScaledPixel(); | |
//Control.Typeface = view.Font.ToExtendedTypeface(Context); | |
} | |
} | |
/// <summary> | |
/// Set text based on nullable value | |
/// </summary> | |
/// <param name="view"></param> | |
private void SetNullableText(NullableDatePicker view) | |
{ | |
if (view.NullableDate == null) | |
Control.Text = string.Empty; | |
} | |
/// <summary> | |
/// Set the placeholder | |
/// </summary> | |
/// <param name="view"></param> | |
private void SetPlaceholder(NullableDatePicker view) | |
{ | |
Control.Hint = view.Placeholder; | |
} | |
/// <summary> | |
/// Sets the color of the placeholder text. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetPlaceholderTextColor(NullableDatePicker view) | |
{ | |
if (view.PlaceholderTextColor != Color.Default) | |
{ | |
Control.SetHintTextColor(view.PlaceholderTextColor.ToAndroid()); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Xamarin.Forms.Platform.iOS; | |
using Xamarin.Forms; | |
using System.ComponentModel; | |
using UIKit; | |
using Foundation; | |
using System; | |
using CoreGraphics; | |
using NullableDateAPP.Controls; | |
using NullableDateAPP.iOS.Renderer; | |
using NullableDateAPP.iOS.Extensions; | |
[assembly: ExportRenderer(typeof(NullableDatePicker), typeof(NullableDatePickerRenderer))] | |
namespace NullableDateAPP.iOS.Renderer | |
{ | |
public class NullableDatePickerRenderer : DatePickerRenderer | |
{ | |
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e) | |
{ | |
base.OnElementChanged(e); | |
var view = Element as NullableDatePicker; | |
if (view != null) | |
{ | |
SetFont(view); | |
SetTextAlignment(view); | |
SetBorder(view); | |
SetNullableText(view); | |
SetPlaceholderTextColor(view); | |
ResizeHeight(); | |
} | |
} | |
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) | |
{ | |
base.OnElementPropertyChanged(sender, e); | |
var view = (NullableDatePicker)Element; | |
if (e.PropertyName == NullableDatePicker.FontProperty.PropertyName) | |
SetFont(view); | |
else if (e.PropertyName == NullableDatePicker.XAlignProperty.PropertyName) | |
SetTextAlignment(view); | |
else if (e.PropertyName == NullableDatePicker.HasBorderProperty.PropertyName) | |
SetBorder(view); | |
else if (e.PropertyName == NullableDatePicker.NullableDateProperty.PropertyName) | |
SetNullableText(view); | |
else if (e.PropertyName == NullableDatePicker.PlaceholderTextColorProperty.PropertyName) | |
SetPlaceholderTextColor(view); | |
ResizeHeight(); | |
} | |
/// <summary> | |
/// Sets the text alignment. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetTextAlignment(NullableDatePicker view) | |
{ | |
switch (view.XAlign) | |
{ | |
case TextAlignment.Center: | |
Control.TextAlignment = UITextAlignment.Center; | |
break; | |
case TextAlignment.End: | |
Control.TextAlignment = UITextAlignment.Right; | |
break; | |
case TextAlignment.Start: | |
Control.TextAlignment = UITextAlignment.Left; | |
break; | |
} | |
} | |
/// <summary> | |
/// Sets the font. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetFont(NullableDatePicker view) | |
{ | |
UIFont uiFont; | |
if (view.Font != Font.Default && (uiFont = view.Font.ToUIFont()) != null) | |
Control.Font = uiFont; | |
else if (view.Font == Font.Default) | |
Control.Font = UIFont.SystemFontOfSize(17f); | |
} | |
/// <summary> | |
/// Sets the border. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetBorder(NullableDatePicker view) | |
{ | |
Control.BorderStyle = view.HasBorder ? UITextBorderStyle.RoundedRect : UITextBorderStyle.None; | |
} | |
/// <summary> | |
/// Set text based on nullable value | |
/// </summary> | |
/// <param name="view"></param> | |
private void SetNullableText(NullableDatePicker view) | |
{ | |
if (view.NullableDate == null) | |
Control.Text = string.Empty; | |
} | |
/// <summary> | |
/// Resizes the height. | |
/// </summary> | |
private void ResizeHeight() | |
{ | |
if (Element.HeightRequest >= 0) return; | |
var height = Math.Max(Bounds.Height, | |
new UITextField { Font = Control.Font }.IntrinsicContentSize.Height) * 2; | |
Control.Frame = new CGRect(0.0f, 0.0f, (nfloat)Element.Width, (nfloat)height); | |
Element.HeightRequest = height; | |
} | |
/// <summary> | |
/// Sets the color of the placeholder text. | |
/// </summary> | |
/// <param name="view">The view.</param> | |
private void SetPlaceholderTextColor(NullableDatePicker view) | |
{ | |
if (!string.IsNullOrEmpty(view.Placeholder)) | |
{ | |
var foregroundUIColor = view.PlaceholderTextColor.ToUIColor(CheckColorExtensions.SeventyPercentGrey); | |
var backgroundUIColor = view.BackgroundColor.ToUIColor(); | |
var targetFont = Control.Font; | |
Control.AttributedPlaceholder = new NSAttributedString(view.Placeholder, targetFont, foregroundUIColor, backgroundUIColor); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment