.net 如何在 WPF 应用程序中更改 DateTimePicker 的格式(例如 dd/MMM/yyyy)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/641577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change format (e.g. dd/MMM/yyyy) of DateTimePicker in WPF application
提问by
I want to Change the Format of date selected in DateTimePicker in WPF Application
我想更改在 WPF 应用程序中的 DateTimePicker 中选择的日期格式
回答by Fernando García
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:
我正在处理这个问题。我找到了一种执行此自定义格式的简单方法,希望对您有所帮助。您需要做的第一件事是在您的 XAML 中将特定样式应用到您当前的 DatePicker,就像这样:
<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.
正如您在这部分注意到的那样,当时存在一个名为 DateTimeFormatter 的转换器来绑定到“PART_TextBox”的 Text 属性。此转换器接收包含您的自定义格式的转换器参数。最后,我们在 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;
}
}
}
I hope this help to you. Please let me know for any issue or suggesting for improve.
我希望这对你有帮助。请让我知道任何问题或建议改进。
回答by Legish
Thread.CurrentThread.CurrentCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern = "dd-MMM-yyyy";
回答by Hallgeir Engen
Add this style to your xaml or App.xaml file
将此样式添加到您的 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>
回答by Stuart
In XAML:
在 XAML 中:
<toolkit:DatePicker SelectedDateFormat="Long" />
or
或者
<toolkit:DatePicker SelectedDateFormat="Short" />
回答by Simon
Thanks to @Fernando García for the basis of this.
感谢@Fernando García 为此提供的基础。
I have written a DateFormat attached property for DatePicker that lets you provide a format string for display and input.
我为 DatePicker 编写了一个 DateFormat 附加属性,它允许您提供用于显示和输入的格式字符串。
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:
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;
}
}
}
回答by Dee
DatePicker1.SelectedDate = DatePicker1.SelectedDate.Value.ToString("dd/MM/yyyy")
回答by abhilash
Typically the date time format is stored in a resource file, because this would help in internationalization of the app.
通常日期时间格式存储在资源文件中,因为这将有助于应用程序的国际化。
You can pick up the format from the resource file and use a ToString(DATE_FORMAT)
您可以从资源文件中选择格式并使用 ToString(DATE_FORMAT)
In your case you might want to use
在您的情况下,您可能想要使用
dateTimePicker.SelectedDate.ToString("dd-MMM-yyyy");
回答by Vitaliy Ulantikov
As for me, changing environment to change DatePickerformat (like Thread.CurrentCulture) is not a good idea.
Sure, you can create Controlderived from DatePickerand implement dependency property like Format, but this costs too much effort.
至于我,改变环境来改变DatePicker格式(如Thread.CurrentCulture)不是一个好主意。当然,您可以创建Control衍生自DatePicker并实现像 那样的依赖属性Format,但这会花费太多精力。
Simple and elegant solution I found is binding value not to SelectedDateitself, but to some unused property (I used ToolTipproperty for this) and update this property when SelectedDate is changed.
我发现的简单而优雅的解决方案是将值绑定SelectedDate到一些未使用的属性(我ToolTip为此使用了属性)并在 SelectedDate 更改时更新此属性。
C# implementation for one-way binding looks like this:
单向绑定的 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# should look like this:
XAML+C# 应如下所示:
XAML:
XAML:
<DatePicker ToolTip="{Binding Date Mode=TwoWay}"
SelectedDateChanged="DatePicker_SelectedDateChanged"/>
C#:
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;
}
For two-way implementation handle ToolTipChangedevent the same way to update SelectedDate.
对于双向实现处理ToolTipChanged事件的方式与更新方式相同SelectedDate。
回答by Shelly
Try This
尝试这个
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
DateLabel.Content = Convert.ToDateTime(datePicker1.Text).ToString("dd-MM-yyyy");
}

