DatePickerControl

March 13, 2026 · View on GitHub

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

PropertyTypeDescription
SelectedDateDateTime?The currently selected date. null means no date is set (displays today as placeholder).
MinDateDateTime?Minimum selectable date. Dates before this are clamped and grayed out in the calendar.
MaxDateDateTime?Maximum selectable date. Dates after this are clamped and grayed out in the calendar.
CultureCultureInfoLocale controlling date format and first day of week. Defaults to CultureInfo.CurrentCulture.
DateFormatOverridestring?Overrides the short date pattern from the culture (e.g. "dd/MM/yyyy").
FirstDayOfWeekOverrideDayOfWeek?Overrides the culture's first day of the week for the calendar grid.
PromptstringLabel text displayed before the date segments.
IsEnabledboolWhether the control accepts input.
IsCalendarOpenboolRead-only. Whether the calendar popup is currently visible.
BackgroundColorColorBackground color (unfocused).
ForegroundColorColorForeground color (unfocused).
FocusedBackgroundColorColorBackground color when focused.
FocusedForegroundColorColorForeground color when focused.
SegmentBackgroundColorColorBackground of the active date segment.
SegmentForegroundColorColorForeground of the active date segment.

Events

EventSignatureDescription
SelectedDateChangedEventHandler<DateTime?>Fires when the selected date changes.
GotFocusEventHandlerFires when the control receives focus.
LostFocusEventHandlerFires when the control loses focus (also closes the calendar).

Keyboard Shortcuts

Inline Mode (segments)

KeyAction
Left / RightMove between date segments (month, day, year)
Tab / Shift+TabMove between segments (passes focus if at first/last segment)
UpIncrement the focused segment by 1
DownDecrement the focused segment by 1
0-9Type digits directly into the focused segment
Enter / SpaceOpen the calendar popup

Calendar Popup Mode

KeyAction
Left / RightMove highlight by one day
Up / DownMove highlight by one week
Page UpPrevious month
Page DownNext month
Ctrl+Page UpPrevious year
Ctrl+Page DownNext year
HomeJump to first day of the month
EndJump to last day of the month
TJump to today
Enter / SpaceSelect the highlighted day and close the calendar
EscapeClose 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/MaxDate are 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 PropertyDescriptionClassicTheme Default
DatePickerBackgroundColorUnfocused backgroundnull (inherits from window)
DatePickerForegroundColorUnfocused foregroundnull (inherits from window)
DatePickerFocusedBackgroundColorFocused backgroundColor.Blue
DatePickerFocusedForegroundColorFocused foregroundColor.White
DatePickerSegmentBackgroundColorActive segment backgroundColor.DarkBlue
DatePickerSegmentForegroundColorActive segment foregroundColor.White
DatePickerDisabledForegroundColorDisabled textColor.Grey
DatePickerCalendarTodayColorToday highlight in calendarColor.Cyan1
DatePickerCalendarSelectedColorSelected day highlightColor.Blue
DatePickerCalendarHeaderColorCalendar header textColor.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());

Back to Controls Reference | TimePickerControl