自定义WinForms日历控件开发

在开发类似于Outlook 2007的个人日历/预约日历时,需要一个月份日历。市面上有许多优秀的日历控件,但它们并不完全符合需求。因此,开始开发自己的日历控件。在这个过程中,不仅实现了一个月历,还实现了一个日期选择器控件。

同时,考虑将文化适应性(culture awareness)集成到控件中,以便不同国家的人们也可以使用。这比想象的要复杂得多,遇到了很多关于文化支持的问题,包括框架中的一些棘手的错误;稍后会有更详细的说明。

想在这里分享结果,因为CodeProject多次为问题提供了解决方案。

类图

在DatePicker控件中有一个新属性AllowPromptAsInput。将其设置为true允许输入包括当前日期分隔符在内的日期,该分隔符由FormatProvider属性设置。

功能

文化适应性 - 意味着可以设置使用的文化和日历;

通过CalendarDimensions属性可调整可见子日历的数量;

在颜色和字体方面完全可定制;

可以加载或保存颜色表;

可调整RTL或LTR布局;

可以调整是否使用最短或缩写的星期名称;

可以调整是否显示周头和周尾;

可调整非工作日(对于工作周选择模式);

可调整每周的第一天;

可调整星期名称(完整/缩写/最短);

可调整月份名称(完整/缩写);

可调整月份/天字符串模式;

支持设置最小/最大日期;

使用鼠标滚轮滚动;

不同的选择模式(单日/工作周/整周/手动);

可调整手动选择模式下最多可选的天数;

加粗日期集合;

新的:扩展的加粗日期(类别和相应的颜色定义);

新的:手动选择模式现在支持使用CTRL键选择多个范围;

新的:日期分隔符现在在选择器控件中有效输入;

可调整滚动变化(点击箭头时滚动多少个月);

日期选择器控件支持键盘导航;

支持禁用状态;

使用代码

只需将控件项目添加到现有解决方案中并引用它。该控件是用VS 2010构建的,目标框架版本是3.5。

文化适应性的要点

关于控件的文化适应性,必须承认不能保证所有内容都正确显示和计算。如果有错误,请随时发布消息。

如前所述,在实现文化适应性时,遇到了框架中的一些棘手的错误。其中一个错误如下:

System.Globalization.Calendar实现中的GetWeekOfYear()方法。每个日历都有一个MinSupportedDateTime属性。如果想从该日期获取年份的周数,那么在某些情况下,尽管传递给方法的日期是有效的,但会得到一个ArgumentOutOfRangeException。

受影响的日历实现有:

Hijri、UmAlQura、Hebrew、Persian、JulianCalendar,以及所有EastAsianLunisolarCalendar的实现。

另一个错误是在日本日历中,GetYear()方法对于特定日期范围返回0。

很可能没有找到所有关于日历实现的错误,所以如果设置了一个不寻常的日历,如JapaneseLunisolarCalendar,可能会抛出异常。

自定义MonthControl

控件的渲染由一个单独的渲染器类处理。如果想要自定义绘图,那么可以通过派生自抽象基类或默认渲染器来实现自己的渲染器。

对于实现IXmlSerializable的颜色表类也是如此。

调整MonthCalendar控件

需要注意的一点是,只能设置非中性文化。原因是中性文化没有DateTimeFormat属性的值,需要这个值用于不同的原因。

要调整可见的子月视图,可以直接设置CalendarDimensions属性,或者使用设计器。

使用ColorTable属性,可以调整使用的颜色,包括是否使用渐变颜色和渐变模式。

调整DatePicker控件

选择器文本框部分中的日期使用短日期模式显示,也可以调整这个模式。这个模式也用于解析日期。

选择器控件有一个CheckDate事件,可以在其中检查并设置输入的日期是否有效。如果无效,则使用InvalidBackColor和InvalidForeColor属性的颜色显示日期。

另一个重要属性是ClosePickerOnDayClick。通过它,可以调整选择器是否在点击一天时关闭,无论该天是否已经被选中。

扩展加粗日期

DatePicker和MonthCalendar控件现在有两个新属性:

BoldedDateCategoryCollection BoldedDatesCollection

第一个集合保存加粗日期的类别定义,第二个集合保存加粗日期及其对应的类别。

定义加粗日期的原始属性仍然像以前一样工作。

使用原生数字

两个控件都有一个新属性:

UseNativeDigits

这个属性将控件中显示的任何数字转换为包含当前Culture的NativeDigits的字符串。

如果将当前Culture设置为波斯语(fa-IR),那么这个文化就没有阿拉伯数字,而是波斯数字。

例如,波斯语日期01.01.1390在格式dd/MM/yyyy中将显示为:

۰۱ / ۰۱ / ۱۳۹۰

让向展示一张设置日期选择器的Culture和CultureCalendar为波斯语的图片:

此外,手动输入的日期也使用原生数字。

请注意,显示的星期名称(可能还有月份名称)可能是错误的,因为这些值是从.Net Framework CultureInfo类中获取的,特别是波斯语(fa-IR)CultureInfo类的波斯语星期名称(在这种情况下是最短的星期名称)是错误的,这是由于波斯语(fa-IR)CultureInfo类的一个错误/特性。

事件

月控件有以下重要事件:

DateChanged:通过上下文菜单更改月份或年份时发生;

DateClicked:在'Day'选择模式下点击一天时发生;

DateSelected:选择日期或日期范围时发生;

SelectionExtendEnd:选择扩展结束时发生;

日期选择器有一个重要事件:

ValueChanged:日期值更改时发生;

两个控件有一个共同的事件:

ActiveDateChanged:当鼠标悬停在一个日期上时发生。

2009年12月1日:初次发布。

2011年10月12日:扩展了带类别的加粗日期。

2011年11月22日:扩展了支持多个范围的选择。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485