2009-03-13 4 views

Antwort

0

Typischerweise ist das Datum Zeitformat wird in einer Ressourcendatei gespeichert weil das bei der Internationalisierung der App helfen würde.

Sie können das Format aus der Ressourcendatei aufnehmen und verwenden Sie einen ToString(DATE_FORMAT)

In Ihrem Fall Sie könnte

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

In XAML verwenden möchten:

<toolkit:DatePicker SelectedDateFormat="Long" /> 

oder

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

+1 Ich frage mich, ob es eine Möglichkeit gibt, eine benutzerdefinierte Datumsformat-Zeichenfolge in XAML bereitzustellen. –

+0

Diese Eigenschaft ist für das DatePickerTextBox-Steuerelement in der ursprünglichen Frage nicht verfügbar. – Wouter

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

Kompiliert das überhaupt? – code4life

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

Dies ändert sich in UI-Steuerelement, aber nicht in Viewmodel-Eigenschaft. Ich bekomme das gleiche Format des Computer Datumsformats. irgendeine Idee bitte? –

14

Ich hatte mit diesem Problem in der Vergangenheit. Ich habe eine einfache Möglichkeit gefunden, dieses benutzerdefinierte Format auszuführen, und ich hoffe, dass dies Ihnen hilft. Das erste, was Sie tun müssen, ist einen bestimmten Stil zu Ihrem aktuellen Datepicker gelten genau wie dieser, in 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> 

Wie Sie an dieser Stelle bemerken kann, gibt es einen Konverter DateTimeFormatter zu der Zeit genannt machen Bindung in die Text-Eigenschaft der "PART_TextBox". Dieser Konverter empfängt den Konverterparameter, der Ihr benutzerdefiniertes Format enthält. Schließlich fügen wir den Code in C# für den DateTimeFormatter-Konverter hinzu.

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

Ich hoffe, dass diese Hilfe für Sie. Bitte lassen Sie mich für jedes Problem oder Vorschlag zur Verbesserung wissen.

0

Für mich ist die Änderung der Umgebung zu ändern DatePicker Format (wie Thread.CurrentCulture) ist keine gute Idee. Sicher, Sie können Control abgeleitet von DatePicker erstellen und Abhängigkeitseigenschaft wie Format implementieren, aber das kostet zu viel Aufwand.

einfache und elegante Lösung gefunden I-Wert nicht verbindlich zu SelectedDate selbst, sondern bis zu einem gewissen ungenutzten Sach (I verwenden ToolTip Eigenschaft für diesen) und diese Eigenschaft aktualisieren, wenn SelectedDate geändert wird.

C# -Implementierung für Einweg-Bindung sieht wie folgt aus:

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

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# sollte wie folgt aussehen

Für Zweiwege-i mplementation Handle ToolTipChanged Ereignis auf die gleiche Weise zu aktualisieren SelectedDate.

2

Dank @Fernando García für die Grundlage.

Ich habe eine DateFormat angefügte Eigenschaft für DatePicker geschrieben, mit der Sie eine Formatzeichenfolge für die Anzeige und Eingabe bereitstellen können.

Für die Eingabe wird versucht, das bereitgestellte Format zu parsen, indem versucht wird, es mit dem aktuellen Kulturformat zu analysieren.

Beispiel für die Verwendung mit dem Format Frage:

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

Die Dateformat angebracht Eigenschaft ist:

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

Ich habe versucht, die oben genannte Klasse zu verwenden, um das richtige Datumsformat zu erhalten. Auf den ersten Blick dachte ich, es funktioniert wie erwartet. Aber nach einigen Momenten entdeckte ich, dass ich dieses Datum im richtigen Format erhalte, wenn ich ein Datum auswähle. Für z.B. DD/MM/JJJJ. Als ich dann den Fokus auf andere Steuerung legte, sah ich, dass das Datum wieder in das Standardformat, d. H. MM.dd.yyyy, konvertiert wurde. Von diesem habe ich beobachtet, dass DateSeparator bleibt, was spezifiziert ist, aber das Format des Datums ändert sich, sobald der DatePicker seinen Fokus verliert. – Vishal

3

diese Art Ihrem XAML hinzufügen oder 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-Datei Diese

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