Every DatePicker in a MahApps application is styled without any markup on your side, and so is the calendar that drops out of it. On top of that the library adds a watermark and a clear button, both through the same attached properties a TextBox uses.

The implicit style
Styles/Controls.xaml contains keyless styles for DatePicker, DatePickerTextBox and Calendar. Merging that dictionary — which the quick start does — is all it takes:
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
Three of them are needed because a DatePicker is three controls: the picker itself, the DatePickerTextBox inside it, and the Calendar in the drop-down.
To extend rather than replace, base your own style on the keyed one:
<Style BasedOn="{StaticResource MahApps.Styles.DatePicker}" TargetType="{x:Type DatePicker}">
<Setter Property="mah:TextBoxHelper.ClearTextButton" Value="True" />
</Style>
The styles
| Style | Target | |
|---|---|---|
MahApps.Styles.DatePicker |
DatePicker |
the picker. What the implicit style applies |
MahApps.Styles.DatePickerTextBox |
DatePickerTextBox |
the text box inside it |
MahApps.Styles.DatePickerTextBox.TimePickerBase |
DatePickerTextBox |
the same, used by TimePicker and DateTimePicker; it only forwards the automation properties from the picker to the box |
MahApps.Styles.DatePicker.Win10 (on develop) |
DatePicker |
the picker in the Windows 10 look |
MahApps.Styles.DatePicker.WinUI (on develop) |
DatePicker |
and in the WinUI one |
Besides the look, the picker style also sets three behavioural defaults you may want to change: SelectedDateFormat to Short, IsTodayHighlighted to True, and CalendarStyle to MahApps.Styles.Calendar.Base.
The two Windows looks
On develop the picker has a style in each of the two Windows sets, and either one is the text box of that set with a calendar behind the button.
MahApps.Styles.DatePicker.Win10 takes the fill, the two-unit frame and the padding MahApps.Styles.TextBox.Win10 has, and the accent runs round the frame while the caret is in the field.
MahApps.Styles.DatePicker.WinUI stands on that one: a translucent fill, rounded corners, and a border that is a touch stronger along its bottom edge and turns into the accent there once the caret is in. That edge is a border of its own in the template and two units thick either way, so the picker stays as tall as it was and nothing under it moves. The brush for it is ControlsHelper.BottomBorderBrush, which is on ControlsHelper.
Each of the two hands its own calendar to the drop-down, MahApps.Styles.Calendar.Win10 and MahApps.Styles.Calendar.WinUI, so the square day cells and the round ones come along with the field.
The Win10 and WinUI sets apply them to every DatePicker in the tree they are merged into. One picker at a time:
<DatePicker Style="{StaticResource MahApps.Styles.DatePicker.WinUI}" />
Two habits came with the pickers of those two sets, both of them what the TextBox of the same set already did. The clear button is there only while the caret is in the field and something is written in it, the way a UWP box shows its delete button, which is TextBoxHelper.ClearTextButtonFollowsFocus. And a picker that is switched off says so with the disabled colours of its set instead of with a veil drawn over it, which is ControlsHelper.DisabledVisualElementVisibility set to Collapsed along with ControlsHelper.DisabledBorderBrush. The Metro picker asks for neither and looks the way it always has.
The template behind all three keeps its inner grid inside the frame and clips it to the corners that frame leaves over, so with a corner radius the fill of a button no longer runs over the rounding. The text box, the password box and the rich text box are built the same way.
The clear button
ClearTextButton puts an ✕ next to the calendar button, which empties the picker.
<DatePicker mah:TextBoxHelper.ClearTextButton="True" />
The mechanism is worth knowing, because it is not the one the other input controls use. The button is in the template unconditionally, and a trigger collapses it while TextBoxHelper.ButtonCommand is null — which it is by default. Setting ClearTextButton="True" fires a second trigger that puts MahAppsCommands.ClearControlCommand into ButtonCommand, and that is what brings the button back.
Two things follow from that:
- Setting your own
ButtonCommandalso makes the button appear, and it replaces the clearing rather than adding to it. That is the way to turn the ✕ into something else — a "today" button, for instance. ClearControlCommandrefuses to run unlessClearTextButtonisTrueand the picker is not read-only, so the button is disabled rather than misleading in those cases.
The command is public and works on more than a picker — it clears a TextBox, ComboBox or TimePicker the same way, and can be invoked from anywhere:
<Button Command="{x:Static mah:MahAppsCommands.ClearControlCommand}"
CommandTarget="{Binding ElementName=StartDate}"
Content="Clear" />
Watermark
WPF's own DatePickerTextBox shows Select a date when it is empty. TextBoxHelper.Watermark replaces that with your own text, and the floating variant keeps it visible once a date has been picked:

<DatePicker mah:TextBoxHelper.Watermark="Start date" />
<DatePicker mah:TextBoxHelper.Watermark="Start date"
mah:TextBoxHelper.UseFloatingWatermark="True" />
The calendar
The drop-down is an ordinary Calendar, styled through the picker's CalendarStyle. Three calendar styles ship with the library:
| Style | |
|---|---|
MahApps.Styles.Calendar.Base |
what a DatePicker uses in its drop-down |
MahApps.Styles.Calendar |
the same plus the control font and size; what a standalone Calendar gets from the implicit style |
MahApps.Styles.Calendar.DateTimePicker |
the base with a quieter border, for the drop-down of a DateTimePicker |

All three build on MahApps.Styles.CalendarItem, MahApps.Styles.CalendarDayButton and MahApps.Styles.CalendarButton, which is where the individual days, the month and year buttons and the header live. Restyling one day cell means replacing CalendarDayButtonStyle rather than the whole calendar.
<DatePicker CalendarStyle="{StaticResource MyCalendar}" />
Helper properties
Three helpers reach a DatePicker, and their full property tables are on their own pages: DatePickerHelper for the drop-down button, TextBoxHelper for the watermark and the clear button, and ControlsHelper for the border, the corner radius and read-only.
What the style itself sets, since those are the values you would be overriding:
| Property | To |
|---|---|
DatePickerHelper.DropDownButtonContent |
the calendar glyph, as Path geometry |
DatePickerHelper.DropDownButtonContentTemplate |
the template that draws that geometry |
TextBoxHelper.IsMonitoring |
True |
TextBoxHelper.ButtonWidth |
22 |
TextBoxHelper.ButtonFontSize |
MahApps.Font.Size.Button.ClearText |
TextBoxHelper.ButtonTemplate |
the chromeless button template |
ControlsHelper.FocusBorderBrush |
MahApps.Brushes.TextBox.Border.Focus |
ControlsHelper.MouseOverBorderBrush |
MahApps.Brushes.TextBox.Border.MouseOver |
ButtonCommand is deliberately absent from that list — it is set by the trigger described above, not by the style.
The drop-down button's content and template are set as a pair, so replacing the calendar icon means dealing with both. DatePickerHelper has the detail.
Read-only
DatePicker has no IsReadOnly of its own. ControlsHelper.IsReadOnly fills the gap: it disables the drop-down button, makes the text box read-only, and stops the clear command from running.
<DatePicker mah:ControlsHelper.IsReadOnly="True" SelectedDate="{Binding StartDate}" />
That leaves the date readable and selectable, which is what a disabled picker does not.
Validation
Validation.ErrorTemplate is set to MahApps.Templates.ValidationError, so a failing validation rule on SelectedDate is drawn the way it is on every other MahApps input control. How the popup behaves is ValidationHelper.
Related
TimePicker and DateTimePicker are MahApps controls of their own rather than styles of a WPF one, and they reuse both the DatePickerTextBox.TimePickerBase style and DatePickerHelper.