DatePickerControl
Locale-aware date picker with segmented editing, calendar popup, and min/max date constraints.
Overview
The DatePickerControl displays an inline date editor with segmented month/day/year fields. Users can type digits directly into each segment, use arrow keys to increment/decrement values, or open a calendar popup overlay for visual date selection. The segment order and separator are derived from the configured CultureInfo.
See also: TimePickerControl
Quick Start
var datePicker = Controls.DatePicker("Birthday:")
.WithSelectedDate(new DateTime(2000, 1, 15))
.OnSelectedDateChanged((s, date) =>
{
// date is DateTime?
})
.Build();
window.AddControl(datePicker);
Builder API
Create a DatePickerBuilder through the Controls factory:
var builder = Controls.DatePicker("Select date:");
Value Methods
.WithSelectedDate(DateTime? date) // Set the initial date
.WithMinDate(DateTime? date) // Set minimum allowed date
.WithMaxDate(DateTime? date) // Set maximum allowed date
Format Methods
.WithCulture(CultureInfo culture) // Set locale for format and first day of week
.WithFormat(string format) // Override the date format pattern (e.g. "yyyy-MM-dd")
.WithFirstDayOfWeek(DayOfWeek day) // Override the first day of the week in the calendar
Layout Methods
.WithPrompt(string prompt) // Set the label text (default: "Date:")
.WithAlignment(HorizontalAlignment align) // Horizontal alignment
.WithVerticalAlignment(VerticalAlignment) // Vertical alignment
.WithMargin(int left, int top, int right, int bottom)
.WithMargin(int margin) // Uniform margin on all sides
.WithWidth(int width) // Fixed width
.Visible(bool visible) // Initial visibility
Identity Methods
.WithName(string name) // Name for FindControl<T>() lookups
.WithTag(object tag) // Arbitrary user data
.WithStickyPosition(StickyPosition pos) // Sticky positioning
.StickyTop() // Shorthand for StickyPosition.Top
.StickyBottom() // Shorthand for StickyPosition.Bottom
Event Methods
.OnSelectedDateChanged(EventHandler<DateTime?> handler)
.OnSelectedDateChanged(WindowEventHandler<DateTime?> handler) // includes Window reference
.OnGotFocus(EventHandler handler)
.OnGotFocus(WindowEventHandler<EventArgs> handler)
.OnLostFocus(EventHandler handler)
.OnLostFocus(WindowEventHandler<EventArgs> handler)
Building
DatePickerControl control = builder.Build();
// Implicit conversion is also supported:
DatePickerControl control = Controls.DatePicker("Date:")
.WithSelectedDate(DateTime.Today);
Properties
| Property | Type | Description |
|---|---|---|
SelectedDate |
DateTime? |
The currently selected date. null means no date is set (displays today as placeholder). |
MinDate |
DateTime? |
Minimum selectable date. Dates before this are clamped and grayed out in the calendar. |
MaxDate |
DateTime? |
Maximum selectable date. Dates after this are clamped and grayed out in the calendar. |
Culture |
CultureInfo |
Locale controlling date format and first day of week. Defaults to CultureInfo.CurrentCulture. |
DateFormatOverride |
string? |
Overrides the short date pattern from the culture (e.g. "dd/MM/yyyy"). |
FirstDayOfWeekOverride |
DayOfWeek? |
Overrides the culture's first day of the week for the calendar grid. |
Prompt |
string |
Label text displayed before the date segments. |
IsEnabled |
bool |
Whether the control accepts input. |
IsCalendarOpen |
bool |
Read-only. Whether the calendar popup is currently visible. |
BackgroundColor |
Color |
Background color (unfocused). |
ForegroundColor |
Color |
Foreground color (unfocused). |
FocusedBackgroundColor |
Color |
Background color when focused. |
FocusedForegroundColor |
Color |
Foreground color when focused. |
SegmentBackgroundColor |
Color |
Background of the active date segment. |
SegmentForegroundColor |
Color |
Foreground of the active date segment. |
Events
| Event | Signature | Description |
|---|---|---|
SelectedDateChanged |
EventHandler<DateTime?> |
Fires when the selected date changes. |
GotFocus |
EventHandler |
Fires when the control receives focus. |
LostFocus |
EventHandler |
Fires when the control loses focus (also closes the calendar). |
Keyboard Shortcuts
Inline Mode (segments)
| Key | Action |
|---|---|
| Left / Right | Move between date segments (month, day, year) |
| Tab / Shift+Tab | Move between segments (passes focus if at first/last segment) |
| Up | Increment the focused segment by 1 |
| Down | Decrement the focused segment by 1 |
| 0-9 | Type digits directly into the focused segment |
| Enter / Space | Open the calendar popup |
Calendar Popup Mode
| Key | Action |
|---|---|
| Left / Right | Move highlight by one day |
| Up / Down | Move highlight by one week |
| Page Up | Previous month |
| Page Down | Next month |
| Ctrl+Page Up | Previous year |
| Ctrl+Page Down | Next year |
| Home | Jump to first day of the month |
| End | Jump to last day of the month |
| T | Jump to today |
| Enter / Space | Select the highlighted day and close the calendar |
| Escape | Close the calendar without changing the date |
Mouse Interaction
- Click on a segment focuses that segment for editing
- Click on the
▼indicator toggles the calendar popup open/closed - Click a day in the calendar selects it and closes the popup
- Click
◄/►in the calendar header navigates months - Click
[ Today ]jumps to today and selects it - Mouse wheel on calendar scrolls months
Calendar Popup
Pressing Enter or Space on the inline date, or clicking the ▼ indicator, opens a calendar overlay rendered through the portal system. Clicking on date segments focuses them for editing without opening the calendar. The calendar displays:
- A month/year header with navigation arrows
- Day-of-week column headers (locale-aware abbreviations)
- A grid of days with highlighting for today and the selected date
- Out-of-range days grayed out when
MinDate/MaxDateare set - A "Today" button to jump to the current date
The calendar supports both keyboard and mouse interaction. Clicking a day selects it and closes the popup. Clicking outside the calendar dismisses it.
Locale and CultureInfo
The date format, separator character, and first day of week are all derived from the Culture property:
// US format: MM/dd/yyyy, week starts Sunday
Controls.DatePicker("Date:")
.WithCulture(new CultureInfo("en-US"))
// German format: dd.MM.yyyy, week starts Monday
Controls.DatePicker("Datum:")
.WithCulture(new CultureInfo("de-DE"))
// Japanese format: yyyy/MM/dd
Controls.DatePicker()
.WithCulture(new CultureInfo("ja-JP"))
// ISO format override regardless of culture
Controls.DatePicker()
.WithFormat("yyyy-MM-dd")
.WithFirstDayOfWeek(DayOfWeek.Monday)
Theme Properties
| Theme Property | Description | ClassicTheme Default |
|---|---|---|
DatePickerBackgroundColor |
Unfocused background | null (inherits from window) |
DatePickerForegroundColor |
Unfocused foreground | null (inherits from window) |
DatePickerFocusedBackgroundColor |
Focused background | Color.Blue |
DatePickerFocusedForegroundColor |
Focused foreground | Color.White |
DatePickerSegmentBackgroundColor |
Active segment background | Color.DarkBlue |
DatePickerSegmentForegroundColor |
Active segment foreground | Color.White |
DatePickerDisabledForegroundColor |
Disabled text | Color.Grey |
DatePickerCalendarTodayColor |
Today highlight in calendar | Color.Cyan1 |
DatePickerCalendarSelectedColor |
Selected day highlight | Color.Blue |
DatePickerCalendarHeaderColor |
Calendar header text | Color.Yellow |
Common Patterns
Date Range Validation
DatePickerControl? startPicker = null;
DatePickerControl? endPicker = null;
startPicker = Controls.DatePicker("From:")
.WithSelectedDate(DateTime.Today)
.OnSelectedDateChanged((s, date) =>
{
if (endPicker != null && date.HasValue)
endPicker.MinDate = date;
})
.Build();
endPicker = Controls.DatePicker("To:")
.WithMinDate(DateTime.Today)
.OnSelectedDateChanged((s, date) =>
{
if (startPicker != null && date.HasValue)
startPicker.MaxDate = date;
})
.Build();
window.AddControl(startPicker);
window.AddControl(endPicker);
Combined Date and Time Form
window.AddControl(Controls.DatePicker("Date:")
.WithName("meetingDate")
.WithMinDate(DateTime.Today)
.Build());
window.AddControl(Controls.TimePicker("Start:")
.WithName("startTime")
.With24HourFormat()
.WithSelectedTime(new TimeSpan(9, 0, 0))
.Build());
window.AddControl(Controls.Button("Schedule")
.OnClick((s, e, w) =>
{
var date = w.FindControl<DatePickerControl>("meetingDate")?.SelectedDate;
var start = w.FindControl<TimePickerControl>("startTime")?.SelectedTime;
if (date.HasValue && start.HasValue)
{
var dateTime = date.Value + start.Value;
// Process...
}
})
.Build());