2009-03-13 12 views

Respuesta

0

Normalmente, el formato de fecha y hora se almacena en un archivo de recursos, porque esto ayudaría en la internacionalización de la aplicación.

Usted puede recoger el formato del archivo de recursos y utilizar un ToString(DATE_FORMAT)

En su caso es posible que desee utilizar

dateTimePicker.SelectedDate.ToString("dd-MMM-yyyy"); 
3

En XAML:

<toolkit:DatePicker SelectedDateFormat="Long" /> 

o

<toolkit:DatePicker SelectedDateFormat="Short" /> 
+0

+1 Me pregunto si hay una manera de proporcionar una cadena de formato datetime de custome en XAML. –

+0

Esta propiedad no está disponible para el control DatePickerTextBox en la pregunta original. – Wouter

1
DatePicker1.SelectedDate = DatePicker1.SelectedDate.Value.ToString("dd/MM/yyyy") 
+1

¿Esto incluso compila? – code4life

3
Thread.CurrentThread.CurrentCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone(); 
Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern = "dd-MMM-yyyy";  
+0

esto está cambiando en el control de la IU pero no en la propiedad del modelo de vista. Estoy obteniendo el mismo formato de formato de fecha de la computadora. alguna idea, por favor? –

14

Me estaba manejando con este problema rencetly. Encontré una manera simple de realizar este formato personalizado y espero que esto te ayude. Lo primero que hay que hacer es aplicar un estilo específico para su DatePicker actual al igual que este, en su 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> 

Como se puede notar en esta parte, existe un convertidor llamado DateTimeFormatter en el momento de hacer la unión a la propiedad Text del "PART_TextBox". Este convertidor recibe el parámetro del convertidor que incluye su formato personalizado. Finalmente agregamos el código en C# para el convertidor DateTimeFormatter.

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; 
     } 
    } 
} 

Espero que esto te ayude. Por favor, avíseme para cualquier problema o sugerencia para mejorar.

0

En cuanto a mí, cambiar el entorno para cambiar el formato DatePicker (como Thread.CurrentCulture) no es una buena idea. Claro, puede crear Control derivado de DatePicker e implementar propiedad de dependencia como Format, pero esto cuesta demasiado esfuerzo.

La solución simple y elegante que encontré es el valor de enlace no a SelectedDate, sino a alguna propiedad no utilizada (utilicé la propiedad ToolTip para esto) y actualizo esta propiedad cuando se cambia SelectedDate.

C# aplicación de un solo sentido miradas de unión como esta:

DatePicker datePicker = new DatePicker(); 
    datePicker.SetBinding(ToolTipProperty, "Date"); 
    datePicker.SelectedDateChanged += (s, ea) => 
     { 
      DateTime? date = datePicker.SelectedDate; 
      string value = date != null ? date.Value.ToString("yyyy-MM-dd") : null; 
      datePicker.ToolTip = value; 
     }; 

XAML + C# debe tener este aspecto:

XAML:

<DatePicker ToolTip="{Binding Date Mode=TwoWay}" 
      SelectedDateChanged="DatePicker_SelectedDateChanged"/> 

C#:

private void DatePicker_SelectedDateChanged(object sender, EventArgs ea) 
{ 
    DatePicker datePicker = (DatePicker)sender; 
    DateTime? date = datePicker.SelectedDate; 
    string value = date != null ? date.Value.ToString("yyyy-MM-dd") : null; 
    datePicker.ToolTip = value; 
} 

Para bidireccional i Mplementation handle ToolTipChanged evento de la misma manera para actualizar SelectedDate.

2

Gracias a @Fernando García por la base de esto.

He escrito un DateFormat adjunta propiedad de DatePicker que le permite proporcionar una cadena de formato para la visualización y la entrada.

Para la entrada se intentará analizar utilizando el formato proporcionado, cayendo de nuevo a intentar analizar con el formato de la cultura actual.

Ejemplo de uso con el formato de la pregunta: ¿

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

La propiedad DateFormat adjunto es:

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; 
     } 
    } 
} 
+0

Intenté utilizar la clase mencionada anteriormente para obtener el formato de fecha correcto. A primera vista, pensé que funcionaba como se esperaba. Pero después de algunos momentos descubrí que cuando selecciono una fecha, obtengo esa fecha en el formato correcto. Por ej. dd.MM.aaaa. Luego, cuando moví el foco sobre otro control, vi que esa fecha se convirtió nuevamente al formato predeterminado, es decir, MM.dd.aaaa. De esto observé que DateSeparator sigue siendo el especificado, pero el formato de la fecha cambia tan pronto como el DatePicker pierde su foco. – Vishal

3

Añadir este estilo a su XAML o App.xaml el archivo

<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> 
0

Try este

private void UserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     DateLabel.Content = Convert.ToDateTime(datePicker1.Text).ToString("dd-MM-yyyy"); 
    } 
Cuestiones relacionadas