Skip to content

Instantly share code, notes, and snippets.

@MarcAlx
Last active July 12, 2024 15:02
Show Gist options
  • Save MarcAlx/bc28f4921b9411cd8d391b90f0b4f0c8 to your computer and use it in GitHub Desktop.
Save MarcAlx/bc28f4921b9411cd8d391b90f0b4f0c8 to your computer and use it in GitHub Desktop.
DateTime Picker MAUI
using System.Windows.Input;
using Microsoft.Maui.Controls;
namespace SO.Commons.MultiPlatform.Views.Controls;
/// <summary>
/// Wrapper arround a DatePicker and a TimePicker to create a DateTimePicker
///
/// Design is mean't to be overrided via ControlTemplate see: https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/controltemplate
///
/// e.g :
/// <ControlTemplate x:Key="MyDateTimePickerTemplate" x:DataType="myControls:DateTimePicker">
/// <HorizontalStackLayout>
/// <DatePicker Date = "{TemplateBinding DatePartValue}" />
/// <Label Text="|"/>
/// <TimePicker Time = "{TemplateBinding TimePartValue}" />
/// </HorizontalStackLayout >
/// </ControlTemplate>
///
/// Use asis :
///
/// <myControls:DateTimePicker Value={Binding ADateTime}
/// ControlTemplate={StaticResource MyDateTimePickerTemplate}/>
///
/// </summary>
public class DateTimePicker : ContentView
{
#region DatePart
/// <summary>
/// Identifies the <see cref="DatePartValueProperty"/> bindable property.
/// </summary>
public static readonly BindableProperty DatePartValueProperty =
BindableProperty.Create(nameof(DatePartValue),
typeof(DateTime),
typeof(DateTimePicker),
DateTime.Now,
BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
if (bindable is DateTimePicker dtp && newValue is DateTime dt)
{
dtp.Value = new DateTime(dt.Year, dt.Month, dt.Day, dtp.Value.Hour,dtp.Value.Minute, dtp.Value.Second);
}
});
/// <summary>
/// Value
/// </summary>
/// <seealso cref="DatePartValueProperty"/>
public DateTime DatePartValue
{
get => (DateTime)GetValue(DatePartValueProperty);
set => SetValue(DatePartValueProperty, value);
}
#endregion
#region Timepart
/// <summary>
/// Identifies the <see cref="TimePartValueProperty"/> bindable property.
/// </summary>
public static readonly BindableProperty TimePartValueProperty =
BindableProperty.Create(nameof(TimePartValue),
typeof(TimeSpan),
typeof(DateTimePicker),
TimeSpan.FromMilliseconds(0),
BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
if (bindable is DateTimePicker dtp && newValue is TimeSpan ts)
{
dtp.Value = new DateTime(dtp.Value.Year, dtp.Value.Month, dtp.Value.Day, ts.Hours, ts.Minutes, ts.Seconds);
}
});
/// <summary>
/// TimePartValue
/// </summary>
/// <seealso cref="DatePartValueProperty"/>
public TimeSpan TimePartValue
{
get => (TimeSpan)GetValue(TimePartValueProperty);
set => SetValue(TimePartValueProperty, value);
}
#endregion
#region Value
/// <summary>
/// Identifies the <see cref="ValueProperty"/> bindable property.
/// </summary>
public static readonly BindableProperty ValueProperty =
BindableProperty.Create(nameof(Value),
typeof(DateTime),
typeof(DateTimePicker),
DateTime.Now,
BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
if (bindable is DateTimePicker dtp && newValue is DateTime dt)
{
dtp.DatePartValue = dt.Date;
dtp.TimePartValue = dt.TimeOfDay;
}
});
/// <summary>
/// Value
/// </summary>
/// <seealso cref="ValueProperty"/>
public DateTime Value
{
get => (DateTime)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
#endregion
/// <summary>
/// Picker for date part
/// </summary>
private DatePicker datePicker = new DatePicker();
/// <summary>
/// Picker for time part
/// </summary>
private TimePicker timePicker = new TimePicker();
public DateTimePicker()
{
//watch for picker value change
datePicker.BindingContext = this;
datePicker.SetBinding(DatePicker.DateProperty, nameof(DatePartValue));
timePicker.BindingContext = this;
timePicker.SetBinding(TimePicker.TimeProperty, nameof(TimePartValue));
Content = new HorizontalStackLayout
{
Spacing = 20,
Children = {
datePicker,
timePicker
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment