65.9K
CodeProject 正在变化。 阅读更多。
Home

# 可空 DateEdit 控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.13/5 (8投票s)

2003年6月16日

4分钟阅读

viewsIcon

129974

downloadIcon

816

一个可空的 C# DateEdit 控件

Sample Image - DateEdit.gif

引言

.NET 的 DateTimePicker (DTP) 控件相当不错,直到你需要一个可空日期。我最近遇到了一个需要可空日期的场景,并发现了这个问题。一个很好的例子是 ShippedDate。如果产品尚未发货,此属性应包含什么?同样,DateTime 结构不支持 null 值。.NET Beta 版有一个 DateTime.Empty 值,但已被移除。我看到一些使用 DTP 的变通方法,即使用复选框来指示 null 值,但我认为这会让最终用户感到困惑。DateEdit 控件是我为解决此问题而努力的成果。当值为 null 时,它会显示为空格式 "__/__/____"。此控件的重点是快速直接的数据输入。它目前不提供下拉日历,但我有一个想法,可以为那些需要更多“花哨”功能的人构建一个不同的控件。

设计考虑因素

无效日期

阻止输入无效日期值可能很困难。例如,尝试在 DTP 中输入 2/29/2000。因此,我决定不尝试任何除了允许数字输入之外的用户输入验证。这意味着 03/45/____ 可能会被输入到 DateEdit 控件中。为了解决这个问题,我在 OnLeave 事件中触发了一个 InvalidDate 事件。这可用于显示消息,或更改背景颜色,或您选择的任何其他方法来通知用户无效值。

不可为空的 DateTime 结构

DateTime 结构不允许 Null 值。在花了一些时间考虑编写一个 NullableDateTime 结构后,我决定不这样做。为了使其正常工作,它需要成为标准 DateTime 结构的精确替代品。由于结构不能继承,您需要实现 DateTime 结构中包含的 EVERY 方法。一个相对直接的解决方案是定义一个新的 DateTime 常量 NullValue,它等于 MinValue ( 01/01/0001 )。这可以防止将 MinValue 用作有效日期,但我认为我可以接受这一点。

Null 日期持久化

下一个问题是如何处理持久化到数据库中的 NullValue 日期。您可以简单地将 01/01/0001 持久化到数据库,并记住此值代表 Null。我不喜欢这个解决方案,因为直接对数据库进行查询的人可能不知道这一点。如果我想知道哪些订单尚未发货,SQL 会是什么样子?

Select ... Where ShippedDate Is Null
Select ... Where ShippedDate = 1/1/0001
我认为第一个 SQL 看起来更符合逻辑。另外,如果有人查看表中的原始列数据,他们会看到 1/1/0001,这看起来像一个真实日期。Null 值会更明显。

NullValue (1/1/0001) 持久化到数据库确实有一个优点,那就是不需要转换为 DBNull

持久化 Null 日期意味着一些额外的工作。一个支持 Null 值并能自动转换为 DBNullDateTime 结构将是理想的解决方案,但由于 DateTime 不能为 null,我们必须使用变通方法。(为您增加了更多工作)变通方法是在数据库检索和持久化期间添加代码,将 NullValue 转换为 DBNull

DateEdit 功能

我已包含对国际日期格式的支持,并对此功能进行了“一些”测试。如果您发现任何错误,请告诉我。

DateEdit 控件基于 MaskedEdit 控件。它使用 2 位数字表示月份和日期。这意味着 2 月 5 日必须输入为 02/05。这在日期输入期间增加了几步不必要的键盘输入。

IsValid 属性对于有效日期或 Null 返回 true。

使用 Value 属性获取/设置 DateTime 值。注意:1/1/0001 或您决定的任何 NullValue 将自动转换为空白掩码。“__/__/____”,具体取决于您的区域设置。

后续步骤

DateEdit 控件专为简单的日期输入而设计。添加下拉月历会使其更具视觉吸引力。如果您输入接近已知日期的日期,例如距离当前日期 +- 1 个月,则月历会很有用。使用月历在 DTP 中输入出生日期,可能会需要一次遍历 10、20、30 年,一次 1 个月。不太可能很快。添加下拉月历意味着构建一个基于 DateEdit、内置 MonthCalendar 和向下箭头按钮的复合控件。让我知道您的想法。DateEditEx 控件将是独立的,这样如果您不需要下拉 MonthCalendar 的额外大小和开销,则不必使用它。

DateEdit 控件目前不支持时间输入。我的经验告诉我,需要时间值的日期最好由代码在内部设置。时间输入会增加用户的输入量,而且我预计准确性不会很高。

这不是一个完美的解决方案,但希望能奏效。如果您有改进的想法,请告诉我。

历史

  • 初始发布:2003 年 6 月 16 日
© . All rights reserved.