How to change format (e.g. dd/MMM/yyyy) of DateTim

2019-01-22 08:44发布

I want to Change the Format of date selected in DateTimePicker in WPF Application

9条回答
狗以群分
2楼-- · 2019-01-22 08:52
Thread.CurrentThread.CurrentCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern = "dd-MMM-yyyy";      
查看更多
戒情不戒烟
3楼-- · 2019-01-22 08:52

Thanks to @Fernando García for the basis of this.

I have written a DateFormat attached property for DatePicker that lets you provide a format string for display and input.

For input it will attempt to parse using the provided format, falling back to trying to parse it with the current culture's format.

Example usage with the question's format:

<DatePicker my:DatePickerDateFormat.DateFormat="dd/MMM/yyyy"/>

The DateFormat attached property is:

public class DatePickerDateFormat
{
    public static readonly DependencyProperty DateFormatProperty =
        DependencyProperty.RegisterAttached("DateFormat", typeof (string), typeof (DatePickerDateFormat),
                                            new PropertyMetadata(OnDateFormatChanged));

    public static string GetDateFormat(DependencyObject dobj)
    {
        return (string) dobj.GetValue(DateFormatProperty);
    }

    public static void SetDateFormat(DependencyObject dobj, string value)
    {
        dobj.SetValue(DateFormatProperty, value);
    }

    private static void OnDateFormatChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
    {
        var datePicker = (DatePicker) dobj;

        Application.Current.Dispatcher.BeginInvoke(
            DispatcherPriority.Loaded, new Action<DatePicker>(ApplyDateFormat), datePicker);
    }

    private static void ApplyDateFormat(DatePicker datePicker)
    {
        var binding = new Binding("SelectedDate")
            {
                RelativeSource = new RelativeSource {AncestorType = typeof (DatePicker)},
                Converter = new DatePickerDateTimeConverter(),
                ConverterParameter = new Tuple<DatePicker, string>(datePicker, GetDateFormat(datePicker))
            };
        var textBox = GetTemplateTextBox(datePicker);
        textBox.SetBinding(TextBox.TextProperty, binding);

        textBox.PreviewKeyDown -= TextBoxOnPreviewKeyDown;
        textBox.PreviewKeyDown += TextBoxOnPreviewKeyDown;

        datePicker.CalendarOpened -= DatePickerOnCalendarOpened;
        datePicker.CalendarOpened += DatePickerOnCalendarOpened;
    }

    private static TextBox GetTemplateTextBox(Control control)
    {
        control.ApplyTemplate();
        return (TextBox) control.Template.FindName("PART_TextBox", control);
    }

    private static void TextBoxOnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key != Key.Return)
            return;

        /* DatePicker subscribes to its TextBox's KeyDown event to set its SelectedDate if Key.Return was
         * pressed. When this happens its text will be the result of its internal date parsing until it
         * loses focus or another date is selected. A workaround is to stop the KeyDown event bubbling up
         * and handling setting the DatePicker.SelectedDate. */

        e.Handled = true;

        var textBox = (TextBox) sender;
        var datePicker = (DatePicker) textBox.TemplatedParent;
        var dateStr = textBox.Text;
        var formatStr = GetDateFormat(datePicker);
        datePicker.SelectedDate = DatePickerDateTimeConverter.StringToDateTime(datePicker, formatStr, dateStr);
    }

    private static void DatePickerOnCalendarOpened(object sender, RoutedEventArgs e)
    {
        /* When DatePicker's TextBox is not focused and its Calendar is opened by clicking its calendar button
         * its text will be the result of its internal date parsing until its TextBox is focused and another
         * date is selected. A workaround is to set this string when it is opened. */

        var datePicker = (DatePicker) sender;
        var textBox = GetTemplateTextBox(datePicker);
        var formatStr = GetDateFormat(datePicker);
        textBox.Text = DatePickerDateTimeConverter.DateTimeToString(formatStr, datePicker.SelectedDate);
    }

    private class DatePickerDateTimeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var formatStr = ((Tuple<DatePicker, string>) parameter).Item2;
            var selectedDate = (DateTime?) value;
            return DateTimeToString(formatStr, selectedDate);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var tupleParam = ((Tuple<DatePicker, string>) parameter);
            var dateStr = (string) value;
            return StringToDateTime(tupleParam.Item1, tupleParam.Item2, dateStr);
        }

        public static string DateTimeToString(string formatStr, DateTime? selectedDate)
        {
            return selectedDate.HasValue ? selectedDate.Value.ToString(formatStr) : null;
        }

        public static DateTime? StringToDateTime(DatePicker datePicker, string formatStr, string dateStr)
        {
            DateTime date;
            var canParse = DateTime.TryParseExact(dateStr, formatStr, CultureInfo.CurrentCulture,
                                                  DateTimeStyles.None, out date);

            if (!canParse)
                canParse = DateTime.TryParse(dateStr, CultureInfo.CurrentCulture, DateTimeStyles.None, out date);

            return canParse ? date : datePicker.SelectedDate;
        }
    }
}
查看更多
爷的心禁止访问
4楼-- · 2019-01-22 08:53

In XAML:

<toolkit:DatePicker SelectedDateFormat="Long" />

or

<toolkit:DatePicker SelectedDateFormat="Short" />
查看更多
贪生不怕死
5楼-- · 2019-01-22 08:59

I was handling with this issue rencetly. I found a simple way to perform this custom format and I hope that this help you. First thing that you need to do is apply a specific style to your current DatePicker just like this, in your XAML:

<DatePicker.Resources>
    <Style TargetType="{x:Type DatePickerTextBox}">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <TextBox x:Name="PART_TextBox" Width="113" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Text="{Binding Path=SelectedDate,Converter={StaticResource DateTimeFormatter},RelativeSource={RelativeSource AncestorType={x:Type DatePicker}},ConverterParameter=dd-MMM-yyyy}" BorderBrush="{DynamicResource BaseBorderBrush}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DatePicker.Resources>

As you can notice at this part, exist a Converter called DateTimeFormatter at the time to make binding to the Text property of the "PART_TextBox". This converter receives the converterparameter that includes your custom format. Finally we add the code in C# for the DateTimeFormatter converter.

public class DateTimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        DateTime? selectedDate = value as DateTime?;

        if (selectedDate != null)
        {
            string dateTimeFormat = parameter as string;
            return selectedDate.Value.ToString(dateTimeFormat);
        }

        return "Select Date";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {

            var valor = value as string;
            if (!string.IsNullOrEmpty(valor))
            {
                var retorno = DateTime.Parse(valor);
                return retorno;
            }

            return null;
        }
        catch
        {
            return DependencyProperty.UnsetValue;
        }
    }
}

I hope this help to you. Please let me know for any issue or suggesting for improve.

查看更多
一纸荒年 Trace。
6楼-- · 2019-01-22 09:03
DatePicker1.SelectedDate = DatePicker1.SelectedDate.Value.ToString("dd/MM/yyyy")
查看更多
兄弟一词,经得起流年.
7楼-- · 2019-01-22 09:08

Add this style to your xaml or App.xaml file

 <Style TargetType="{x:Type DatePickerTextBox}">
     <Setter Property="VerticalContentAlignment" Value="Center"/>
     <Setter Property="Control.Template">
         <Setter.Value>
             <ControlTemplate>
                 <TextBox x:Name="PART_TextBox"
            Text="{Binding Path=SelectedDate, StringFormat='dd.MM.yyyy', 
            RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>
查看更多
登录 后发表回答