如何在日期选择器格式上禁用自动完成



我有一个日期选择器,它有一个控件模板来设置文本框中显示的日期的字符串格式

<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 位数字(,我宁愿显示错误......

感谢您的帮助

通过查看DatePicker源代码,看起来此行为的真正原因是ParseText()用来转换为选定日期DateTime.Parse()方法。

可以通过扩展 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
        }
    }
}

最新更新