WPF Standard Control Demo App › DatePicker
DatePicker Inputs
DatePicker combines a text box for typing a date with a button that opens a calendar popup. The selected date is a nullable DateTime.
The value is a nullable date: bind it to DateTime?
The value of a DatePicker is SelectedDate, a DateTime? that is null when no date is chosen and binds two-way by default. The text box shows it as text, and typing a date and pressing Enter sets it; clearing the text box and pressing Enter set it to null. Bind it to a DateTime? property, for example for a due date that stays empty until the user picks one. Bound to a DateTime property, setting it to null produced a binding error: the source kept its old date, and Validation.HasError became True on the DatePicker.
DisplayDate is the month the calendar shows. A new DatePicker had today’s date, and setting SelectedDate to 2026-04-15 moved DisplayDate to the same day. Setting DisplayDate afterward did not change SelectedDate.
The calendar popup is a Calendar control. IsDropDownOpen tells whether it is open and binds two-way by default. Setting it to True before the window was shown raised no exception, and the popup was open once the window appeared.
The range limits only the calendar
DisplayDateStart and DisplayDateEnd are the first and last dates the calendar offers. With a range of 2026-04-10 to 2026-04-20, the day button for 04-05 in the popup was disabled. The range is not enforced anywhere else. Setting SelectedDate to 04-05 from code, setting Text to “4/5/2026”, and typing “4/5/2026” followed by Enter all left the date at 04-05, without an exception or a DateValidationError. Validate the range in the ViewModel.
A DisplayDateStart later than the selected date does not take effect either: with 04-10 selected, DisplayDateStart = 04-15 was pulled back to 04-10. So for a From and a To DatePicker, binding the To picker’s DisplayDateStart to the From date has no effect while the To picker already holds an earlier date. Check the order of the two dates in the ViewModel.
Use BlackoutDates for days that must not be selected. Unlike the range, blackout dates are enforced: setting SelectedDate to one from code threw ArgumentOutOfRangeException and kept the previous date, and the popup marked the day as blacked out.
| case | result |
|---|---|
| SelectedDate = 04-15: DisplayDate / then DisplayDate = 07-01: SelectedDate | 2026-04-15 / 2026-04-15 |
| out of range from code: SelectedDate = 04-05 | no exception; SelectedDate 2026-04-05 |
| out of range through Text: Text = "4/5/2026" | no exception; SelectedDate 2026-04-05, Text "4/5/2026" |
| out of range typed: "4/5/2026" + Enter | SelectedDate 2026-04-05, Text "4/5/2026", DateValidationError 0 |
| in range typed: "4/18/2026" + Enter | SelectedDate 2026-04-18, Text "4/18/2026", DateValidationError 0 |
| unparsable typed: "abc" + Enter | SelectedDate 2026-04-15, Text "4/15/2026", DateValidationError 1 ("abc") |
| text cleared + Enter | SelectedDate null, Text "", DateValidationError 0 |
| calendar popup, day button 2026-04-05 | IsEnabled False, IsBlackedOut False, IsInactive False |
| calendar popup, day button 2026-04-12 | IsEnabled True, IsBlackedOut False, IsInactive False |
| BlackoutDates 04-12..04-13; SelectedDate = 04-12 from code | ArgumentOutOfRangeException; SelectedDate 2026-04-15 |
| calendar popup, day button 2026-04-12 | IsEnabled True, IsBlackedOut True |
| SelectedDate 04-10, then DisplayDateStart = 04-15 | no exception; DisplayDateStart 2026-04-10, SelectedDate 2026-04-10 |
| Text = "4/15/2026" | no exception; SelectedDate 2026-04-15, Text "4/15/2026" |
| Text = "2026-04-15" | no exception; SelectedDate 2026-04-15, Text "4/15/2026" |
| Text = "April 15, 2026" | no exception; SelectedDate 2026-04-15, Text "4/15/2026" |
| Text = "15/4/2026" | no exception; SelectedDate null, Text "" |
Range, blackout dates, and input, with xml:lang="en-US". Measured on .NET 10 / Windows 11.
Setting Text versus typing into the box
Dates here were parsed and displayed with xml:lang="en-US". Text is the date as text. Unlike SelectedDate, it does not bind two-way by default. Setting it is parsed immediately with the DatePicker’s culture: “4/15/2026”, “2026-04-15”, and “April 15, 2026” all gave 2026-04-15, and Text then read “4/15/2026”. A string that cannot be parsed (“15/4/2026” in en-US) cleared SelectedDate to null.
Typing into the text box behaves differently: “abc” followed by Enter raised DateValidationError, kept the previous date, and put the previous text back. Handle DateValidationError to tell the user that typed text was not accepted; otherwise the text box silently goes back to the previous date.
Defaults that come from the style and the culture
Two defaults come from the default style and differ from the property metadata. IsTodayHighlighted is False in the metadata, but the default style sets True, so today is marked unless you turn it off. With False, the day button’s display state changed from Today to RegularDay and its today marker became transparent. The button stayed enabled, so today can still be selected.
SelectedDateFormat has only two values, Short and Long. It is Long in the metadata, and the effective default is Short, set by the default style. The output of each value in several cultures, and how to show another format, are measured in Customising the DatePicker Display Format in WPF. The article changes the format through the DatePicker’s text part, because SelectedDate itself holds a DateTime, not text.
FirstDayOfWeek, the day in the leftmost column, was passed on to the popup’s Calendar with the same value. A new DatePicker takes it from the thread’s current culture: it was Sunday for en-US and ja-JP, and Monday for de-DE and fr-FR. Set it explicitly only when the calendar should differ from the user’s culture.
Trying it in the demo app

The DatePicker page of the demo app has a section for each of SelectedDate, DisplayDate, DisplayDateStart and DisplayDateEnd, FirstDayOfWeek, IsDropDownOpen, IsTodayHighlighted, SelectedDateFormat, and Text. The DisplayDate section binds one DatePicker’s DisplayDate to another DatePicker’s selection, one month ahead of today; the range section runs from last Monday to next Friday; the IsDropDownOpen check box follows the popup as well as controlling it; and the Text section binds Text one-way from a text box. The “Show Code” link under each section displays its XAML. The following XAML is the DisplayDate Range (Start/End) section (DatePickerUsageControl.xaml), with the styles and the surrounding GroupBoxes left out and the namespace declarations added. DateTimeAdvancedConverter is a converter in the demo app that computes last Monday and next Friday from today. converters is the prefix for the demo app’s own converters:
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:converters="clr-namespace:WPFStandardControlDemoApp.Common.Converters">
<DatePicker x:Name="DisplayDateStartSourceDatePicker"
SelectedDate="{Binding Source={x:Static sys:DateTime.Now},
Converter={converters:DateTimeAdvancedConverter Operation=Previous, TargetDay=Monday},
Mode=OneTime}" />
<DatePicker x:Name="DisplayDateEndSourceDatePicker"
SelectedDate="{Binding Source={x:Static sys:DateTime.Now},
Converter={converters:DateTimeAdvancedConverter Operation=Next, TargetDay=Friday},
Mode=OneTime}" />
<DatePicker x:Name="DisplayDateRangeDatePicker"
DisplayDateEnd="{Binding SelectedDate, ElementName=DisplayDateEndSourceDatePicker}"
DisplayDateStart="{Binding SelectedDate, ElementName=DisplayDateStartSourceDatePicker}"
SelectedDate="{x:Static sys:DateTime.Now}" />
</StackPanel>
The third DatePicker already has today selected. Moving the start to a day after today in the first DatePicker therefore does not narrow the range past today, as described under DisplayDateStart.
Related controls and articles
- Customising the DatePicker Display Format in WPF — measured output of
SelectedDateFormatby culture, and how to show a custom format. - TextBox — the DatePicker’s text part is a
DatePickerTextBox, which derives from TextBox.
Source code and how it was measured
Every behavior on this page was measured by running it on .NET 10 / Windows 11, using DatePickerDemoScene in this site’s screenshot tool. Typing was reproduced by setting the text of the DatePicker’s text part and sending an Enter key event, and the calendar was checked by opening the popup and reading its day buttons.