Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DatePicker Handlers #543

Merged
merged 6 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ void UpdateFont()
EditText.SetTextSize(ComplexUnitType.Sp, (float)Element.FontSize);
}

[PortHandler]
void UpdateMaximumDate()
{
if (_dialog != null)
Expand All @@ -201,6 +202,7 @@ void UpdateMaximumDate()
}
}

[PortHandler]
void UpdateMinimumDate()
{
if (_dialog != null)
Expand Down
1 change: 1 addition & 0 deletions src/Compatibility/Core/src/AppHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public static IAppHostBuilder RegisterCompatibilityRenderers(this IAppHostBuilde
{
typeof(Button),
typeof(ContentPage),
typeof(DatePicker),
typeof(Editor),
typeof(Entry),
typeof(Label),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS
{
[PortHandler]
internal class NoCaretField : UITextField
{
public NoCaretField() : base(new RectangleF())
Expand All @@ -32,6 +33,7 @@ public DatePickerRenderer()

}

[PortHandler]
protected override UITextField CreateNativeControl()
{
return new NoCaretField { BorderStyle = UITextBorderStyle.RoundedRect };
Expand Down Expand Up @@ -219,11 +221,14 @@ void UpdateCharacterSpacing()
if (textAttr != null)
Control.AttributedText = textAttr;
}

[PortHandler]
void UpdateMaximumDate()
{
_picker.MaximumDate = Element.MaximumDate.ToNSDate();
}

[PortHandler]
void UpdateMinimumDate()
{
_picker.MinimumDate = Element.MinimumDate.ToNSDate();
Expand Down
4 changes: 3 additions & 1 deletion src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ void SetupMauiLayout()
verticalStack.Add(new CheckBox());
verticalStack.Add(new CheckBox { BackgroundColor = Color.LightPink });
verticalStack.Add(new CheckBox { IsChecked = true, Color = Color.Aquamarine });


verticalStack.Add(new DatePicker());

verticalStack.Add(new Editor());
verticalStack.Add(new Editor { Text = "Editor" });
verticalStack.Add(new Editor { Text = "Predictive Text Off", IsTextPredictionEnabled = false });
Expand Down
2 changes: 1 addition & 1 deletion src/Controls/src/Core/DatePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Microsoft.Maui.Controls
{
public class DatePicker : View, IFontElement, ITextElement, IElementConfiguration<DatePicker>
public partial class DatePicker : View, IFontElement, ITextElement, IElementConfiguration<DatePicker>
{
public static readonly BindableProperty FormatProperty = BindableProperty.Create(nameof(Format), typeof(string), typeof(DatePicker), "d");

Expand Down
7 changes: 7 additions & 0 deletions src/Controls/src/Core/HandlerImpl/DatePicker.Impl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Microsoft.Maui.Controls
{
public partial class DatePicker : IDatePicker
{

}
}
30 changes: 30 additions & 0 deletions src/Core/src/Core/IDatePicker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;

namespace Microsoft.Maui
{
/// <summary>
/// Represents a View that allows the user to select a date.
/// </summary>
public interface IDatePicker : IView
{
/// <summary>
/// Gets the format of the date to display to the user.
/// </summary>
string Format { get; set; }

/// <summary>
/// Gets the displayed date.
/// </summary>
DateTime Date { get; set; }

/// <summary>
/// Gets the minimum DateTime selectable.
/// </summary>
DateTime MinimumDate { get; }

/// <summary>
/// Gets the maximum DateTime selectable.
/// </summary>
DateTime MaximumDate { get; }
}
}
94 changes: 94 additions & 0 deletions src/Core/src/Handlers/DatePicker/DatePickerHandler.Android.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Android.App;

namespace Microsoft.Maui.Handlers
{
public partial class DatePickerHandler : AbstractViewHandler<IDatePicker, MauiDatePicker>
{
DatePickerDialog? _dialog;

protected override MauiDatePicker CreateNativeView()
{
var mauiDatePicker = new MauiDatePicker(Context)
{
ShowPicker = ShowPickerDialog,
HidePicker = HidePickerDialog
};

var date = VirtualView?.Date;

if (date != null)
_dialog = CreateDatePickerDialog(date.Value.Year, date.Value.Month, date.Value.Day);

return mauiDatePicker;
}

internal DatePickerDialog? DatePickerDialog { get { return _dialog; } }

protected override void DisconnectHandler(MauiDatePicker nativeView)
{
if (_dialog != null)
{
_dialog.Hide();
_dialog.Dispose();
_dialog = null;
}

base.DisconnectHandler(nativeView);
}

protected virtual DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
{
var dialog = new DatePickerDialog(Context!, (o, e) =>
{
if (VirtualView != null)
VirtualView.Date = e.Date;
}, year, month, day);

return dialog;
}

public static void MapFormat(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateFormat(datePicker);
}

public static void MapDate(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateDate(datePicker);
}

public static void MapMinimumDate(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateMinimumDate(datePicker, handler._dialog);
}

public static void MapMaximumDate(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateMaximumDate(datePicker, handler._dialog);
}

void ShowPickerDialog()
{
if (VirtualView == null)
return;

var date = VirtualView.Date;
ShowPickerDialog(date.Year, date.Month, date.Day);
}

void ShowPickerDialog(int year, int month, int day)
{
if (_dialog == null)
_dialog = CreateDatePickerDialog(year, month, day);
else
_dialog.UpdateDate(year, month, day);

_dialog.Show();
}

void HidePickerDialog()
{
_dialog?.Hide();
}
}
}
14 changes: 14 additions & 0 deletions src/Core/src/Handlers/DatePicker/DatePickerHandler.Standard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace Microsoft.Maui.Handlers
{
public partial class DatePickerHandler : AbstractViewHandler<IDatePicker, object>
{
protected override object CreateNativeView() => throw new NotImplementedException();

public static void MapFormat(DatePickerHandler handler, IDatePicker datePicker) { }
public static void MapDate(DatePickerHandler handler, IDatePicker datePicker) { }
public static void MapMinimumDate(DatePickerHandler handler, IDatePicker datePicker) { }
public static void MapMaximumDate(DatePickerHandler handler, IDatePicker datePicker) { }
}
}
23 changes: 23 additions & 0 deletions src/Core/src/Handlers/DatePicker/DatePickerHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Microsoft.Maui.Handlers
{
public partial class DatePickerHandler
{
public static PropertyMapper<IDatePicker, DatePickerHandler> DatePickerMapper = new PropertyMapper<IDatePicker, DatePickerHandler>(ViewHandler.ViewMapper)
{
[nameof(IDatePicker.Format)] = MapFormat,
[nameof(IDatePicker.Date)] = MapDate,
[nameof(IDatePicker.MinimumDate)] = MapMinimumDate,
[nameof(IDatePicker.MaximumDate)] = MapMaximumDate
};

public DatePickerHandler() : base(DatePickerMapper)
{

}

public DatePickerHandler(PropertyMapper mapper) : base(mapper)
{

}
}
}
99 changes: 99 additions & 0 deletions src/Core/src/Handlers/DatePicker/DatePickerHandler.iOS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using Foundation;
using UIKit;
using RectangleF = CoreGraphics.CGRect;

namespace Microsoft.Maui.Handlers
{
public partial class DatePickerHandler : AbstractViewHandler<IDatePicker, MauiDatePicker>
{
UIDatePicker? _picker;

protected override MauiDatePicker CreateNativeView()
{
MauiDatePicker nativeDatePicker = new MauiDatePicker();

_picker = new UIDatePicker { Mode = UIDatePickerMode.Date, TimeZone = new NSTimeZone("UTC") };

if (NativeVersion.IsAtLeast(14))
{
_picker.PreferredDatePickerStyle = UIDatePickerStyle.Wheels;
}

var width = UIScreen.MainScreen.Bounds.Width;
var toolbar = new UIToolbar(new RectangleF(0, 0, width, 44)) { BarStyle = UIBarStyle.Default, Translucent = true };
var spacer = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);
var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, (o, a) =>
{
SetVirtualViewDate();
nativeDatePicker.ResignFirstResponder();
});

toolbar.SetItems(new[] { spacer, doneButton }, false);

nativeDatePicker.InputView = _picker;
nativeDatePicker.InputAccessoryView = toolbar;

nativeDatePicker.InputView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;
nativeDatePicker.InputAccessoryView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;

nativeDatePicker.InputAssistantItem.LeadingBarButtonGroups = null;
nativeDatePicker.InputAssistantItem.TrailingBarButtonGroups = null;

nativeDatePicker.AccessibilityTraits = UIAccessibilityTrait.Button;

return nativeDatePicker;
}

internal UIDatePicker? DatePickerDialog { get{ return _picker;} }

protected override void ConnectHandler(MauiDatePicker nativeView)
{
if (_picker != null)
_picker.ValueChanged += OnValueChanged;

base.ConnectHandler(nativeView);
}

protected override void DisconnectHandler(MauiDatePicker nativeView)
{
if (_picker != null)
_picker.ValueChanged -= OnValueChanged;

base.DisconnectHandler(nativeView);
}

public static void MapFormat(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateFormat(datePicker);
}

public static void MapDate(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateDate(datePicker);
}

public static void MapMinimumDate(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateMinimumDate(datePicker, handler._picker);
}

public static void MapMaximumDate(DatePickerHandler handler, IDatePicker datePicker)
{
handler.TypedNativeView?.UpdateMaximumDate(datePicker, handler._picker);
}

void OnValueChanged(object? sender, EventArgs? e)
{
SetVirtualViewDate();
}

void SetVirtualViewDate()
{
if (VirtualView == null || _picker == null)
return;

VirtualView.Date = _picker.Date.ToDateTime().Date;
}
}
}
1 change: 1 addition & 0 deletions src/Core/src/Hosting/AppHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static IAppHostBuilder UseMauiHandlers(this IAppHostBuilder builder)
{ typeof(IActivityIndicator), typeof(ActivityIndicatorHandler) },
{ typeof(IButton), typeof(ButtonHandler) },
{ typeof(ICheckBox), typeof(CheckBoxHandler) },
{ typeof(IDatePicker), typeof(DatePickerHandler) },
{ typeof(IEditor), typeof(EditorHandler) },
{ typeof(IEntry), typeof(EntryHandler) },
{ typeof(ILabel), typeof(LabelHandler) },
Expand Down
Loading