如何处理 Windows 窗体 datetimepicker ArgumentOutOfRangeException?
我在 Windows 窗体中的 DateTimePicker 控件中遇到了一个非常具体的错误。该控件具有自定义格式 (MM-YYYY -> 01/2010) - 信用卡的月份/年份。今天是 9 月 29 日。如果用户选择该控件,并使用键盘将月份设置为二月,则该控件将引发 ArgumentOutOfRangeException。没有 2009 年 2 月 29 日这样的日期。这也会发生在 31 日,也就是只有 30 天的月份。
通过将日期设置为“01”就可以很容易地处理此问题,但是用户可以单击日历手动选择 30 日,然后使用键盘选择二月。
当输入发生在 GUI 上而不是真正发生在代码中时,如何捕获此异常?我们尝试在 TextChanged 事件中捕获它,但已经太晚了。异常已经抛出。
对于这种情况,有什么办法可以处理吗?如果控件自动将日期更改为该月的最高值,那就太好了。或者至少如果它通过事件传递异常。
(我知道我们可以捕获 KeyPressed 事件并将日期每次设置为 01,但这感觉很“hacky”)。
I've run into a very specific bug with the DateTimePicker control in Windows Forms. The control has a custom format (MM-YYYY -> 01/2010) - the month/year of a credit card. Today is the 29th of September. If a user selects the control, and uses the keyboard to set the month to February, the control will throw an ArgumentOutOfRangeException. There is no such date as 29-Feb-2009. This will also happen on days as the 31st, moving to a month with only 30 days.
It'd be easy enough to handle this by setting the day to '01', however a user can click the calendar to manually select the 30th, and then use the keyboard to select February.
How can this exception be caught, when the input is happening on the GUI and not really in code? We've tried to catch it in the TextChanged event, but that is already too late. The exception is already thrown.
Is there any way to handle this case? It would be nice if the control automatically changed the day to the highest value for that month. Or at least if it passed the exception through an event.
(I'm aware that we could trap the KeyPressed event and set the day to 01 each time, but this feels 'hacky').
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您只想要月份和年份,在我看来,您首先不应该使用 DatePicker...为什么要向用户提供一个控件,其中包括他们不应该使用的月份中的某一天它?
我建议您使用两个下拉菜单,一个用于年份,一个用于月份。几乎每个在线支付页面的用户都会熟悉这一点,并且可以避免这个问题。
编辑:好的,要回答处理异常的具体问题,您可以使用
Application.ThreadException
事件,但如果可以的话,我会尽量避免这样做。If you only want the month and year, it seems to me that you shouldn't be using a DatePicker in the first place... why present the user with a control which includes the day of the month when they shouldn't be using it?
I would suggest that you either use two dropdowns, one for the year and one for the month. That will be familiar to users from just about every online payment page, and will avoid the problem.
EDIT: Okay, to answer the specific question of handling exceptions, you can use the
Application.ThreadException
event, but I'd try to avoid having to do so if you can.您可以设置 DateTimePicker 的 ShowUpDown属性设置为 true 以便控件成为旋转器而不是日历下拉列表?
Could you set the DateTimePicker's ShowUpDown property to true so that the control becomes a spinner rather than a calendar drop-down?
您不可能只输入月份/年份而不输入日期。如果没有明确指定日期,则使用当前日期。 DateTimePicker 需要所有数据 - 如果您将其隐藏在掩码后面也没关系。
让 DateTimePicker 执行此操作的唯一方法是,典型的 .NET 答案,编写自己的类,该类派生自
DateTimePicker
,并且具有处理无天输入的自定义方式。无论如何,如果不设置日期,您将无法逃脱......
如果可以的话:我建议使用一个
MaskedTextBox
,将掩码设置为“00/0000”(信用卡格式),然后验证输入。There is no way that you can only enter month/year without the day. If no day is explicitly specified the current day is used. The DateTimePicker needs all the data - it doesnt matter if you hide it behind the mask.
The only way to make the DateTimePicker do this is, typical .NET answer, to write your own class that derives from
DateTimePicker
and has a custom way of handling input without days.Anyhow, you will not get away without setting the day ...
If I may: I suggest a
MaskedTextBox
with a mask set to '00/0000' (the credit card format) and then a validation of input.