我有一个DateTimePicker的问题,它很容易重现,感觉就像控件本身的一个错误,但我想确保我没有误解任何东西。
首先,代码非常简单,使用DateTimePicker创建一个WinForms应用程序(我们的项目在.net 4.0中,但我尝试在.net 4.5中创建它,同样的问题)。选择器本身具有自定义格式,格式为“HH:mm”,ShowUpDown也设置为true。 它的验证方法如下:
private void dateTimePicker1_Validating(object sender, CancelEventArgs e)
{
dateTimePicker1.Value = DateTime.Now;
}
在该行上设置断点。
确保在应用程序中有另一个控件,以便您可以跳出DateTimePicker以触发验证。
现在,当在程序中导航到DateTimePicker并在例如小时字段中输入“202”时。这看起来好像你先写了20,当你写第二个“2”时,它现在只是现场的2个。
现在标签超出DateTimePicker。这将触发验证断点。请注意DateTimePicker的值现在是如何设置为20小时的日期。让该行执行并再次监视DateTimePicker的值。现在值os 02代替小时(NOT(!!)DateTime.Now的值)
因此,在将值设置为DateTime.Now后,它会将值更改为DateTimePicker中输入的先前未完成值。
怎么会这样,有什么方法可以解决这个问题吗?
答案 0 :(得分:1)
我无法重复这一点。 Windows版本非常重要,许多常见的控制怪癖在以后的版本中得到修复。我在Windows 8上。
然而,这是一个常见的问题,这些控件在你发起事件时对你做的事情很挑剔。他们倾向于在他们解雇事件后运行代码,这可能会使你所做的事无效。 Validating事件特别棘手,因为它是焦点变化的副作用。如果DTP还没有得到相同的通知那么就会出现问题。非常典型的事件订购麻烦。如果您实际上没有使用验证来验证数据,请支持Leave事件。
听起来很像。这些排序问题的一般解决方案是在事件触发后运行代码并且代码执行不再在控件的代码中。您可以使用表单的BeginInvoke()方法优雅地完成此操作。程序重新进入消息循环后,目标运行,UI又回到静止状态。像这样:
private void dateTimePicker1_Validating(object sender, CancelEventArgs e) {
this.BeginInvoke(new Action(() => dateTimePicker1.Value = DateTime.Now));
}
答案 1 :(得分:0)
在验证事件期间,我会看到您解释的行为,但验证事件完成后,该值将设置为DateTime.Now
。
假设您希望在Validating事件本身期间将DateTimepicker控件的值设置为DateTime.Now
,我发现将值设置为两次会显示值已更改为DateTime.Now
-
dateTimePicker1.Value = DateTime.Now;
dateTimePicker1.Value = DateTime.Now;