2009-03-13 77 views

Trả lời

0

Điển hình là định dạng ngày tháng được lưu trữ trong một tập tin tài nguyên, vì điều này sẽ giúp quốc tế hóa ứng dụng.

Bạn có thể nhận dạng từ các tập tin tài nguyên và sử dụng một ToString(DATE_FORMAT)

Trong trường hợp của bạn, bạn có thể muốn sử dụng

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

Trong XAML:

<toolkit:DatePicker SelectedDateFormat="Long" /> 

hoặc

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

+1 Tôi tự hỏi nếu có cách nào để cung cấp chuỗi định dạng ngày giờ theo yêu cầu trong XAML. –

+0

Thuộc tính này không có sẵn cho điều khiển DatePickerTextBox trong câu hỏi gốc. – Wouter

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

Điều này thậm chí có biên dịch không? – code4life

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

điều này đang thay đổi trong điều khiển giao diện người dùng nhưng không thay đổi trong thuộc tính viewmodel. tôi đang nhận định dạng định dạng ngày của máy tính. bất kỳ ý tưởng xin vui lòng? –

14

Tôi đã xử lý vấn đề này một cách rencetly. Tôi tìm thấy một cách đơn giản để thực hiện định dạng tùy chỉnh này và tôi hy vọng rằng điều này sẽ giúp bạn. Điều đầu tiên mà bạn cần phải làm là áp dụng một phong cách cụ thể để DatePicker hiện tại của bạn như thế này, trong XAML của bạn:

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

Như bạn có thể thấy ở phần này, tồn tại một Chuyển đổi gọi DateTimeFormatter vào thời điểm đó để làm cho ràng buộc vào thuộc tính Văn bản của "PART_TextBox". Công cụ chuyển đổi này nhận được tham biến converter bao gồm định dạng tùy chỉnh của bạn. Cuối cùng, chúng ta thêm mã trong C# cho bộ chuyển đổi 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; 
     } 
    } 
} 

Tôi hy vọng điều này sẽ giúp bạn. Vui lòng cho tôi biết về bất kỳ vấn đề nào hoặc đề xuất cải thiện.

0

Đối với tôi, thay đổi môi trường để thay đổi định dạng DatePicker (như Thread.CurrentCulture) không phải là một ý tưởng hay. Chắc chắn, bạn có thể tạo Control bắt nguồn từ DatePicker và triển khai thuộc tính phụ thuộc như Format, nhưng điều này tốn quá nhiều công sức.

Giải pháp đơn giản và thanh lịch mà tôi thấy là giá trị ràng buộc không phải là SelectedDate, nhưng đối với một số thuộc tính không sử dụng (tôi đã sử dụng thuộc tính ToolTip) và cập nhật thuộc tính này khi SelectedDate bị thay đổi.

C thực hiện # cho một chiều vẻ ràng buộc như thế này:

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# sẽ giống như sau:

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

Đối với hai chiều tôi mplementation handle ToolTipChanged sự kiện theo cùng một cách để cập nhật SelectedDate.

2

Nhờ @Fernando García vì lý do này.

Tôi đã viết thuộc tính DateFormat đính kèm cho DatePicker cho phép bạn cung cấp chuỗi định dạng để hiển thị và nhập.

Để nhập, nó sẽ cố gắng phân tích bằng cách sử dụng định dạng được cung cấp, quay trở lại để cố phân tích cú pháp với định dạng của văn hóa hiện tại.

Ví dụ sử dụng với định dạng của câu hỏi:

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

Thuộc tính DateFormat kèm theo là:

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

Tôi đã cố sử dụng lớp được đề cập ở trên để có định dạng ngày chính xác. Ngay từ cái nhìn đầu tiên tôi nghĩ nó hoạt động như mong đợi. Nhưng sau một thời gian tôi phát hiện ra rằng khi tôi chọn một ngày tôi nhận được ngày đó ở định dạng chính xác. Ví dụ: dd.MM.yyyy. Sau đó, khi tôi di chuyển tiêu điểm qua điều khiển khác, tôi đã xem ngày đó được chuyển đổi thành định dạng mặc định tức là MM.dd.yyyy. Từ này tôi quan sát thấy DateSeparator vẫn còn được chỉ định nhưng định dạng của ngày thay đổi ngay khi DatePicker mất tiêu điểm của nó. – Vishal

3

Thêm phong cách này để XAML hoặc nộp 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

Thử Điều này

private void UserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     DateLabel.Content = Convert.ToDateTime(datePicker1.Text).ToString("dd-MM-yyyy"); 
    } 
Các vấn đề liên quan