222 lines
6.5 KiB
C#
222 lines
6.5 KiB
C#
using Sarand.Net.Mobile.Maui.Layouts;
|
|
using Sarand.Net.Mobile.Maui.Views;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Sarand.Net.Mobile.Maui.Controls
|
|
{
|
|
//=======================================================================
|
|
public class SamDatePicker : SamContentView
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// Definitions.
|
|
|
|
//-------------------------------------------------------------------
|
|
// Data members.
|
|
private bool allowInvalidDate = false;
|
|
private bool invalidDate = true;
|
|
private DateTime previousDate = DateTime.MinValue;
|
|
private SamStackLayout controlLayout = new SamStackLayout() { Orientation = StackOrientation.Horizontal, HorizontalOptions = LayoutOptions.Fill };
|
|
private DatePicker pickerDate = new DatePicker() { IsVisible = false };
|
|
private SamEntry entryDate = new SamEntry() { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.Fill };
|
|
private SamLabel labelResetDate = new SamLabel() { Text = "X", FontAttributes = FontAttributes.Bold, TextColor = Colors.Red, HorizontalOptions = LayoutOptions.Center, VerticalTextAlignment = TextAlignment.Center };
|
|
|
|
//-------------------------------------------------------------------
|
|
// Construction.
|
|
public SamDatePicker()
|
|
{
|
|
// Initialise controls.
|
|
// Date picker. Hidden but used to display calendar.
|
|
DefaultFontSize = pickerDate.FontSize;
|
|
pickerDate.Format = "dd-MMM-yyyy";
|
|
pickerDate.DateSelected += PickerDate_DateSelected;
|
|
// Date display entry.
|
|
entryDate.FontSize = pickerDate.FontSize;
|
|
entryDate.FontFamily = pickerDate.FontFamily;
|
|
entryDate.FontAttributes = pickerDate.FontAttributes;
|
|
entryDate.TextColor = pickerDate.TextColor;
|
|
entryDate.Focused += EntryDate_Focused;
|
|
// 'Reset' date label - to invalidate the date value.
|
|
labelResetDate.FontSize = pickerDate.FontSize;
|
|
labelResetDate.FontFamily = pickerDate.FontFamily;
|
|
|
|
// 'Reset' label tap gesture.
|
|
var tapGestureRecognizer = new TapGestureRecognizer();
|
|
tapGestureRecognizer.Tapped += LabelValidDate_Tapped;
|
|
labelResetDate.GestureRecognizers.Add(tapGestureRecognizer);
|
|
|
|
// Initialise layout.
|
|
Content = controlLayout;
|
|
controlLayout.Children.Add(pickerDate);
|
|
controlLayout.Children.Add(entryDate);
|
|
controlLayout.Children.Add(labelResetDate);
|
|
|
|
RefreshDateDisplay();
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Properties.
|
|
// Configuration.
|
|
public Boolean AllowInvalid
|
|
{
|
|
get { return allowInvalidDate; }
|
|
set
|
|
{
|
|
if (allowInvalidDate = value) return;
|
|
allowInvalidDate = value;
|
|
if (!allowInvalidDate) invalidDate = false;
|
|
RefreshDateDisplay();
|
|
}
|
|
}
|
|
public string Format
|
|
{
|
|
get { return pickerDate.Format; }
|
|
set
|
|
{
|
|
if (pickerDate.Format.Equals(value)) return;
|
|
pickerDate.Format = value;
|
|
}
|
|
}
|
|
public DateTime MinimumDate
|
|
{
|
|
get { return pickerDate.MinimumDate; }
|
|
set { pickerDate.MinimumDate = value; }
|
|
}
|
|
public DateTime MaximumDate
|
|
{
|
|
get { return pickerDate.MaximumDate; }
|
|
set { pickerDate.MaximumDate = value; }
|
|
}
|
|
//-------------------------------------------------------------------
|
|
// Date value.
|
|
public DateTime Date
|
|
{
|
|
get
|
|
{
|
|
if (invalidDate) return DateTime.MinValue;
|
|
return pickerDate.Date;
|
|
}
|
|
set
|
|
{
|
|
if (Date.Equals(value)) return;
|
|
if (!DateUtil.IsValid(value))
|
|
{
|
|
invalidDate = true;
|
|
pickerDate.Date = DateTime.Today;
|
|
}
|
|
else
|
|
{
|
|
invalidDate = false;
|
|
pickerDate.Date = value;
|
|
}
|
|
previousDate = value;
|
|
}
|
|
}
|
|
public String FormattedDate { get { return !invalidDate ? DateUtil.Format(Date, pickerDate.Format) : ""; } }
|
|
//-------------------------------------------------------------------
|
|
// Font.
|
|
public double DefaultFontSize { get; }
|
|
public double FontSize
|
|
{
|
|
get { return pickerDate.FontSize; }
|
|
set
|
|
{
|
|
if (pickerDate.FontSize == value) return;
|
|
pickerDate.FontSize = value;
|
|
entryDate.FontSize = value;
|
|
}
|
|
}
|
|
public String FontFamily
|
|
{
|
|
get { return pickerDate.FontFamily; }
|
|
set
|
|
{
|
|
if (pickerDate.FontFamily == value) return;
|
|
pickerDate.FontFamily = value;
|
|
entryDate.FontFamily = value;
|
|
}
|
|
}
|
|
public FontAttributes FontAttributes
|
|
{
|
|
get { return pickerDate.FontAttributes; }
|
|
set
|
|
{
|
|
if (pickerDate.FontAttributes == value) return;
|
|
pickerDate.FontAttributes = value;
|
|
entryDate.FontAttributes = value;
|
|
}
|
|
}
|
|
public Color TextColor
|
|
{
|
|
get { return pickerDate.TextColor; }
|
|
set
|
|
{
|
|
if (pickerDate.TextColor == value) return;
|
|
pickerDate.TextColor = value;
|
|
entryDate.TextColor = value;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Utilities.
|
|
private void RefreshDateDisplay()
|
|
{
|
|
if (allowInvalidDate)
|
|
{
|
|
pickerDate.IsVisible = false;
|
|
entryDate.IsVisible = true;
|
|
labelResetDate.IsVisible = true;
|
|
}
|
|
else
|
|
{
|
|
pickerDate.IsVisible = true;
|
|
entryDate.IsVisible = false;
|
|
labelResetDate.IsVisible = false;
|
|
}
|
|
String dateValue = "";
|
|
if (!invalidDate)
|
|
dateValue = DateUtil.Format(Date, pickerDate.Format);
|
|
entryDate.Text = dateValue;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// C o n t r o l E v e n t s
|
|
//-------------------------------------------------------------------
|
|
private void PickerDate_DateSelected(object? sender, DateChangedEventArgs e)
|
|
{
|
|
// Date has changed in control.
|
|
invalidDate = !DateUtil.IsValid(e.NewDate);
|
|
RefreshDateDisplay();
|
|
if (DateSelected != null) DateSelected.Invoke(sender, e);
|
|
}
|
|
public event EventHandler<DateChangedEventArgs>? DateSelected;
|
|
//-------------------------------------------------------------------
|
|
private void EntryDate_Focused(object? sender, FocusEventArgs e)
|
|
{
|
|
// Control has gained focus.
|
|
entryDate.Unfocus();
|
|
pickerDate.Focus();
|
|
invalidDate = false;
|
|
RefreshDateDisplay();
|
|
}
|
|
//-------------------------------------------------------------------
|
|
private void LabelValidDate_Tapped(object? sender, EventArgs e)
|
|
{
|
|
// 'Valid' label tapped.
|
|
if (invalidDate) return;
|
|
invalidDate = true;
|
|
DateTime oldDate = previousDate;
|
|
RefreshDateDisplay();
|
|
if (DateSelected != null) DateSelected.Invoke(sender, new DateChangedEventArgs(oldDate, Date));
|
|
previousDate = Date;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|