我有一个日期选择器,它有一个控制模板来设置文本框中显示的日期的字符串格式
<DatePicker x:Name="CustomDatePicker" BorderBrush="LightGray">
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox"
Text="{Binding Path=SelectedDate, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}, StringFormat={}{0:dd/MM/yyyy}, TargetNullValue=''}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
除非用户尝试以文本方式修改日期,否则一切正常。
例如:
如果我们设置“01/01/201”,它将自动完成为“01/01/0201”(通过在开头添加0)
如果我们设置“01/01/9”,它将自动完成“01/01/2009”
所有这些都说这个自动完成功能不直观且可预测,所以我想禁用它。
如果用户放置了无效的日期格式(如果年份部分中没有4位数字),我宁愿显示错误...
感谢您的帮助
答案 0 :(得分:1)
通过查看DatePicker
源代码,看起来这种行为的真正原因是DateTime.Parse()
方法被ParseText()
用于转换为选定日期。
您可以通过扩展DatePicker
控件并在文本到达ParseText()
方法之前预先验证来覆盖此行为。
public class ExtendedDatePicker : DatePicker
{
TextBox _textBox = null;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//subscribe to preview-lost-focus event
_textBox = GetTemplateChild("PART_TextBox") as DatePickerTextBox;
_textBox.AddHandler(TextBox.PreviewLostKeyboardFocusEvent, new RoutedEventHandler(TextBox_PreviewLostFocus), true);
}
private void TextBox_PreviewLostFocus(object sender, RoutedEventArgs e)
{
ValdateText(_textBox.Text);
}
private void ValdateText(string text)
{
if (string.IsNullOrWhiteSpace(text))
return;
// ---- Add/update your valid date-formats here ----
string[] formats = { "dd/MM/yyyy", "dd/M/yyyy", "d/M/yyyy", "d/MM/yyyy",
"MM/dd/yyyy", "M/dd/yyyy", "M/d/yyyy", "MM/d/yyyy"};
CultureInfo culture = CultureInfo.InvariantCulture;
DateTimeStyles styles = DateTimeStyles.None;
DateTime temp;
if (DateTime.TryParseExact(text, formats, culture, styles, out temp))
{
//do nothing
}
else
{
//raise date-picker validation error event like ParseText does
DatePickerDateValidationErrorEventArgs dateValidationError =
new DatePickerDateValidationErrorEventArgs(new FormatException("String was not recognized as a valid DateTime."), text);
OnDateValidationError(dateValidationError);
_textBox.Text = string.Empty; //suppress parsing in base control by emptying text
}
}
}