C# 自.NET 4.0以来XAML绑定日期时间对象的自动更正行为?

C# 自.NET 4.0以来XAML绑定日期时间对象的自动更正行为?,c#,.net,wpf,xaml,.net-4.0,C#,.net,Wpf,Xaml,.net 4.0,在将应用程序从.NET3.5移植到.NET4.0时,我遇到了这个特殊的问题 (文化是nl BE) 我将这样一个文本框(在XAML中)绑定到一个DateTime值,并在PropertyChanged上使用UpdateSourceTrigger(LostFocus按预期工作,但需要进行类型验证): 首先包含此代码段的原因: 我是不是漏掉了什么明显的东西?我无法在3.5中重现这一点。我真的需要使用自己的ValueConverter才能让它正常工作吗?这看起来像是3.5 sp 1中引入的StringF

在将应用程序从.NET3.5移植到.NET4.0时,我遇到了这个特殊的问题

(文化是nl BE)

我将这样一个文本框(在XAML中)绑定到一个DateTime值,并在PropertyChanged上使用UpdateSourceTrigger(LostFocus按预期工作,但需要进行类型验证):

首先包含此代码段的原因:

我是不是漏掉了什么明显的东西?我无法在3.5中重现这一点。我真的需要使用自己的ValueConverter才能让它正常工作吗?这看起来像是3.5 sp 1中引入的
StringFormat
的倒退

DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns('d')
的输出看起来有点不同,但没有什么可以立即解释这种行为(可能是无关的):

.NET3.5.NET4.0 年月日 年月日 dd-MM-yy dd-MM-yy 年月日 yyyy-MM-dd-dd.MMM.yyyy 每天
你试过DatePicker控件吗


我现在使用类似的方法,但我对解决上述问题的其他方法非常感兴趣:

public class CustomDateTimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                          CultureInfo culture)
    {
        if (value == null) { return ""; }
        DateTime dt;
        if (DateTime.TryParse(value.ToString(), CultureInfo.CurrentCulture, 
                              DateTimeStyles.None, out dt))
        {
            return dt.ToShortDateString();
        }
        return "";
    }

    public object ConvertBack(object value, Type targettype, object parameter, 
                              CultureInfo culture)
    {
        if (value == null || value.ToString().Trim().Length==0) { return null; }
        string frmt = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
        DateTime dt;
        if (DateTime.TryParseExact(value.ToString(), frmt, 
                                   CultureInfo.CurrentCulture, 
                                   DateTimeStyles.None, out dt))
        {
            return dt;
        }
        return DependencyProperty.UnsetValue;
    }
}

如果您在PropertyChanged上自动更正,则此行为是“正常的”。 开始退格时,传递给DateTime构造函数的值为:

屏幕>>日期时间(“|”是光标在每个退格之前的位置

(我认为这可能因您的文化而有所不同,因为yy-mm-dd字符串格式)

很难,我不太明白为什么新的日期时间(20,12,10)在文本框中为我定义了2020年。当我使用DateTime.Parse(20,12,10)时,它指导我2012-10-20(yyyy-mm-dd)。除非我们使用自定义的ValueConverter,否则肯定存在某种我们无法控制的自动转换或解析

如果您绝对需要“输入时验证”,我认为定制转换器是一种很好的方式,否则OnLostFocus会像您所说的那样工作得很好


顺便说一句,我的文化是与美国相关的:真的没有简单的解决方法吗?~相关的:(虽然这里也没有真正的解决方法-答案只是说“恢复到lostfocus而不是propertychanged”,但这不是我真正需要的)。它在3.5中确实有效…谢谢你的提示!我考虑过这一点,这确实可以作为“DateTime”解析文本框的一个替代方案,尽管它不能解决类似的StringFormat/PropertyChanged货币问题,但我也遇到了。。。我觉得很奇怪,我应该使用我自己的ValueConverter使其正常工作(这是从3.5sp1中引入的StringFormat向后退了一步)。但是为什么必须使用StringFormat,DatePicker已经基于UI区域性正确显示了所有内容。
FrameworkElement.LanguageProperty.OverrideMetadata(
    typeof(FrameworkElement), 
    new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(
        CultureInfo.CurrentCulture.IetfLanguageTag)));
.NET 3.5 .NET 4.0 d/MM/yyyy d/MM/yyyy d/MM/yy d/MM/yy dd-MM-yy dd-MM-yy dd.MM.yy dd.MM.yy yyyy-MM-dd dd.MMM.yyyy yyyy-MM-dd
public class CustomDateTimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                          CultureInfo culture)
    {
        if (value == null) { return ""; }
        DateTime dt;
        if (DateTime.TryParse(value.ToString(), CultureInfo.CurrentCulture, 
                              DateTimeStyles.None, out dt))
        {
            return dt.ToShortDateString();
        }
        return "";
    }

    public object ConvertBack(object value, Type targettype, object parameter, 
                              CultureInfo culture)
    {
        if (value == null || value.ToString().Trim().Length==0) { return null; }
        string frmt = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
        DateTime dt;
        if (DateTime.TryParseExact(value.ToString(), frmt, 
                                   CultureInfo.CurrentCulture, 
                                   DateTimeStyles.None, out dt))
        {
            return dt;
        }
        return DependencyProperty.UnsetValue;
    }
}
10-12-2000| >> DateTime(200,12,10) >> 10-12-0200

10-12-020|0 >> DateTime(020,12,10) >> 10-12-020 

10-12-00|20  >> DateTime(020,12,10) >> 10-12-020 

10-12-0|20 >> DateTime(20,12,10) >> 10-12-2020