2009-03-13 12 views

ответ

0

Обычно формат даты и времени хранится в файле ресурсов, потому что это поможет в интернационализации приложения.

Вы можете подобрать формат из файла ресурсов и использовать ToString(DATE_FORMAT)

В вашем случае вы можете захотеть использовать

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

В XAML:

<toolkit:DatePicker SelectedDateFormat="Long" /> 

или

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

+1 Интересно, есть ли способ предоставить строку формата datetime custome в XAML. –

+0

Это свойство недоступно для элемента управления DatePickerTextBox в исходном вопросе. – Wouter

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

Разве это даже компилируется? – code4life

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

это изменяется в пользовательском интерфейсе, но не в свойствах viewmodel. Я получаю такой же формат формата даты в компьютере. любая идея, пожалуйста? –

14

Я занимался этой проблемой ранчо. Я нашел простой способ выполнить этот пользовательский формат, и я надеюсь, что это поможет вам. Первое, что вам нужно сделать, это применить определенный стиль к текущему DatePicker так же, как это в вашем 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> 

Как вы можете заметить, в этой части, существует конвертер под названием DateTimeFormatter в то время, чтобы сделать обязательными к свойству Text «PART_TextBox». Этот преобразователь получает преобразователь, который включает ваш собственный формат. Наконец, мы добавляем код в C# для преобразователя 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; 
     } 
    } 
} 

Я надеюсь, что эта помощь вам поможет. Пожалуйста, дайте мне знать по любой проблеме или предложите улучшить.

0

Что касается меня, изменение условий для изменения DatePicker формат (например, Thread.CurrentCulture) - это не очень хорошая идея. Конечно, вы можете создать Control, полученный от DatePicker, и реализовать свойство зависимостей, например Format, но это стоит слишком много усилий.

Простой и элегантный решение, которое я нашел, является обязательным значением не для SelectedDate, а для некоторого неиспользуемого имущества (для этого я использовал свойство ToolTip) и обновил это свойство, когда SelectedDate изменен.

реализация

C# для односторонними связующими выглядит следующим образом:

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# должен выглядеть следующим образом:

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

Для двусторонней передачи mplementation handle ToolTipChanged событие точно так же, как обновление SelectedDate.

2

Спасибо @Fernando García за основу этого.

Я написал прикрепленное свойство DateFormat для DatePicker, которое позволяет вам предоставить строку формата для отображения и ввода.

Для ввода он попытается выполнить синтаксический анализ с использованием предоставленного формата, возвращаясь к тому, чтобы проанализировать его с использованием формата текущей культуры.

Пример использования с форматом на вопрос по:

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

DateFormat придает свойство:

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

Я попытался использовать вышеупомянутый класс, чтобы получить правильный формат даты. На первый взгляд я думал, что он работает так, как ожидалось. Но через несколько мгновений я обнаружил, что, когда я выбираю дату, я получаю эту дату в правильном формате. Напр. ДД.ММ.ГГГГ. Затем, когда я переместил фокус на другой элемент управления, я наблюдал, что эта дата снова преобразуется в формат по умолчанию, то есть MM.dd.yyyy. Из этого я заметил, что DateSeparator остается указанным, но формат даты изменяется, как только DatePicker теряет фокус. – Vishal

3

Добавить этот стиль в свой XAML или App.xaml файл

<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 Это

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