51

I need to change the string format of the DatePickerTextBox in the WPF Toolkit DatePicker, to use hyphens instead of slashes for the seperators.

Is there a way to override this default culture or the display string format?

01-01-2010
benPearce
  • 37,735
  • 14
  • 62
  • 96

10 Answers10

117

I have solved this problem with a help of this code. Hope it will help you all as well.

<Style TargetType="{x:Type DatePickerTextBox}">
 <Setter Property="Control.Template">
  <Setter.Value>
   <ControlTemplate>
    <TextBox x:Name="PART_TextBox"
     Text="{Binding Path=SelectedDate, StringFormat='dd MMM yyyy', 
     RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
   </ControlTemplate>
  </Setter.Value>
 </Setter>
</Style>
petrycol
  • 1,194
  • 1
  • 8
  • 2
  • 1
    thx, it helped me to fully solve to use the date picker to select only month. i quoted your xaml in http://stackoverflow.com/questions/1798513/wpf-toolkit-datepicker-month-year-only/14902905#14902905 . – GameAlchemist Feb 15 '13 at 20:36
  • 5
    Huge fan of this method. I prefer doing this over changing the culture. – Dom Apr 03 '13 at 16:27
  • This is the true answer! Currently, dirty hack is marked as the answer. Pity. – dzendras Apr 14 '13 at 23:10
  • 1
    I can see a few problems with this approach, e.g.: 1. No "select date" watermark; 2. User entered date (`Text`) will not be reflected back to `SelectedDate`. @benPearce, do you have a better solution? – Bolu Nov 21 '14 at 12:34
  • If you do not want to lose the watermark and the rest of default _DatePicker_ functionalities then just base this style on default style (by using `BasedOn="{StaticResource {x:Type DatePickerTextBox}}`). After, you can make the component more appealing by fixing `BorderThickness`, `Padding` and `Margin` (set them to 0 or something). – miselking Apr 11 '17 at 16:05
  • 2
    I have a problem with this solution when I try to edit the date manually/textually. The format I'm using is : dd/MM/yyyy. If I put "11/01/1", at losing focus, it will automatically change to 11/01/2001... If I put "11/01/201", at losing focus, it will automatically change to 11/01/0201... All this to say that the behavior of this autocompletion is not predictable and I would like to disable this function ... I would rather want an error if there is no 4 digits on the year ... – Hyukchan Kwon May 11 '17 at 14:51
  • @HyukchanKwon This may be a little late, but you can add validation logic to the style to enforce your formatting. – Matthew S Nov 14 '18 at 16:07
  • Yet another problem with this solution: it breaks keyboard interaction - you wont be able to focus/interact with the DatePicker using keyboard, only mouse works. – wondra Nov 20 '19 at 10:24
35

It appears, as per Wonko's answer, that you cannot specify the Date format in Xaml format or by inheriting from the DatePicker.

I have put the following code into my View's constructor which overrides the ShortDateFormat for the current thread:

CultureInfo ci = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
ci.DateTimeFormat.ShortDatePattern = "dd-MM-yyyy";
Thread.CurrentThread.CurrentCulture = ci;
benPearce
  • 37,735
  • 14
  • 62
  • 96
  • This is actually what I prefer as not only this makes the date format of the entire system consistent, I also notice that messing with datepicker style mess up things such as placeholder text. – Jacky Cheng Feb 05 '20 at 05:23
  • Best and easy way ! Works across the application if this code is put in `App.cs` constructor :) – Hammas Sep 19 '20 at 08:24
16

The WPF Toolkit DateTimePicker now has a Format property and a FormatString property. If you specify Custom as the format type, you can provide your own format string.

<wpftk:DateTimePicker
    Value="{Binding Path=StartTime, Mode=TwoWay}"
    Format="Custom"
    FormatString="MM/dd/yyyy hh:mmtt"/>
Jordan Parmer
  • 36,042
  • 30
  • 97
  • 119
16

The accepted answer (thanks @petrycol) put me on the right track, but I was getting another textbox border and background color within the actual date picker. Fixed it using the following code.

        <Style TargetType="{x:Type Control}" x:Key="DatePickerTextBoxStyle">
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Background" Value="{x:Null}"/>
        </Style>

        <Style TargetType="{x:Type DatePickerTextBox}" >
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <TextBox x:Name="PART_TextBox"
                             Text="{Binding Path=SelectedDate, StringFormat='dd-MMM-yyyy', RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" Style="{StaticResource DatePickerTextBoxStyle}" >
                        </TextBox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
MarkB
  • 1,783
  • 2
  • 17
  • 32
6

NOTE: This answer (originally written in 2010) is for earlier versions. See other answers for using a custom format with newer versions

Unfortunately, if you are talking about XAML, you are stuck with setting SelectedDateFormat to "Long" or "Short".

If you downloaded the source of the Toolkit along with the binaries, you can see how it is defined. Here are some of the highlights of that code:

DatePicker.cs

#region SelectedDateFormat

/// <summary>
/// Gets or sets the format that is used to display the selected date.
/// </summary>
public DatePickerFormat SelectedDateFormat
{
    get { return (DatePickerFormat)GetValue(SelectedDateFormatProperty); }
    set { SetValue(SelectedDateFormatProperty, value); }
}

/// <summary>
/// Identifies the SelectedDateFormat dependency property.
/// </summary>
public static readonly DependencyProperty SelectedDateFormatProperty =
    DependencyProperty.Register(
    "SelectedDateFormat",
    typeof(DatePickerFormat),
    typeof(DatePicker),
    new FrameworkPropertyMetadata(OnSelectedDateFormatChanged),
    IsValidSelectedDateFormat);

/// <summary>
/// SelectedDateFormatProperty property changed handler.
/// </summary>
/// <param name="d">DatePicker that changed its SelectedDateFormat.</param>
/// <param name="e">DependencyPropertyChangedEventArgs.</param>
private static void OnSelectedDateFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    DatePicker dp = d as DatePicker;
    Debug.Assert(dp != null);

    if (dp._textBox != null)
    {
        // Update DatePickerTextBox.Text
        if (string.IsNullOrEmpty(dp._textBox.Text))
        {
            dp.SetWaterMarkText();
        }
        else
        {
            DateTime? date = dp.ParseText(dp._textBox.Text);

            if (date != null)
            {
                dp.SetTextInternal(dp.DateTimeToString((DateTime)date));
            }
        }
    }
}



#endregion SelectedDateFormat

private static bool IsValidSelectedDateFormat(object value)
{
    DatePickerFormat format = (DatePickerFormat)value;

    return format == DatePickerFormat.Long
        || format == DatePickerFormat.Short;
}

private string DateTimeToString(DateTime d)
{
    DateTimeFormatInfo dtfi = DateTimeHelper.GetCurrentDateFormat();

    switch (this.SelectedDateFormat)
    {
        case DatePickerFormat.Short:
            {
                return string.Format(CultureInfo.CurrentCulture, d.ToString(dtfi.ShortDatePattern, dtfi));
            }

        case DatePickerFormat.Long:
            {
                return string.Format(CultureInfo.CurrentCulture, d.ToString(dtfi.LongDatePattern, dtfi));
            }
    }      

    return null;
}

DatePickerFormat.cs

public enum DatePickerFormat
{
    /// <summary>
    /// Specifies that the date should be displayed 
    /// using unabbreviated days of the week and month names.
    /// </summary>
    Long = 0,

    /// <summary>
    /// Specifies that the date should be displayed 
    ///using abbreviated days of the week and month names.
    /// </summary>
    Short = 1
}
Wonko the Sane
  • 10,623
  • 8
  • 67
  • 92
4

XAML

 <DatePicker x:Name="datePicker" />

C#

var date = Convert.ToDateTime(datePicker.Text).ToString("yyyy/MM/dd");

put what ever format you want in ToString("") for example ToString("dd MMM yyy") and output format will be 7 Jun 2017

Usman Ali
  • 778
  • 8
  • 21
  • There is an Exception here , please review you answer: An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll String was not recognized as a valid DateTime. – abdou_dev Sep 11 '20 at 14:41
1

Converter class:

public class DateFormat : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return null;
        return ((DateTime)value).ToString("dd-MMM-yyyy");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

wpf tag

<DatePicker Grid.Column="3" SelectedDate="{Binding DateProperty, Converter={StaticResource DateFormat}}" Margin="5"/>

Hope it helps

alkk
  • 331
  • 5
  • 11
1

Format exhibited depending on the location but this can be avoided by writing this:

  ValueStringFormat="{}{0:MM'-'yy}" />

And you will be happy!(dd'-'MM'-'yyy)

1

I have solved this problem in an easy way ... Setting options Language in control.

0

As Ben Pearce answered we can use the CultureInfo Class to take care of the Custom Format, I really think is the only logical way. And if you have different dateTimePickers which have different Format, you can use:

CultureInfo ci = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
ci.DateTimeFormat.LongDatePattern = "MMM.yyyy"; //This can be used for one type of DatePicker
ci.DateTimeFormat.ShortDatePattern = "dd.MMM.yyyy"; //for the second type
Thread.CurrentThread.CurrentCulture = ci;

And then you can just change the DateFormat in the .xaml document.

  <DatePicker Name="dateTimePicker1" SelectedDateFormat="Long"  />
Renis1235
  • 4,116
  • 3
  • 15
  • 27