在开发应用程序时,经常需要一个能够展示日期信息的控件,比如预约、会议等。本文介绍的日历视图控件不仅具备这些基本功能,还提供了一些高级特性,如项目阻塞和面向项目的事件处理。这个控件是100%的托管代码,不需要额外的资源,只需要将所有的源代码文件包含到项目中即可使用。
虽然市面上已经有一些类似的控件,但它们往往不能满足特定的需求。因此,开发了这个控件,它在性能上表现良好,但最终的性能表现还取决于实现方式。
要在表单中添加一个日历,只需拖动日历控件即可。它位于System.Windows.Forms.Calendar命名空间下。
这个日历控件不仅可以用于展示基于日期的信息,比如预约和会议,还可以用于展示其他类型的信息。比如,可以考虑使用这个控件来展示系统日志。
日历的视图由ViewStart和ViewEnd属性提供的日期范围决定。根据这两个日期之间的天数,日历会绘制相应的天数。
日历可以以两种模式显示天数:展开模式和简短模式(参见Calendar.DaysMode)。展开模式是第一张截图的风格:天数以列的形式显示,项目根据它们所属的时间放置;而简短模式(第二张截图)则将天数显示在周行上,项目以更紧凑的方式显示。
这里有一个重要的属性是MaximumFullDays(默认值为8)。这个属性表示,当指定的视图少于或等于8天时,天数将以展开模式显示。如果天数超过8天,则会以简短模式显示。
日历会通过LoadItems事件告诉何时向其中添加项目。在该事件中,应该管理如何将信息显示在日历中,通过向日历的Items集合添加项目。每次视图变化时,都会触发该事件。强烈建议使用缓存,而不是每次事件触发时都查询数据库,因为这将严重影响性能。
源代码中的演示项目从内存数组中加载项目,因此这不是最佳示例。
private void calendar1_LoadItems(object sender, CalendarLoadEventArgs e)
{
// 加载与e.DateStart和e.DateEnd日期范围相交的项目
foreach (CalendarItem item in loadedItems)
{
calendar1.Items.Add(item);
}
// 或者更好的做法是...
calendar1.Items.AddRange(loadedItems);
}
强烈建议只添加与日历视图范围相交的项目。可以通过查看Calendar中的DateIntersects实现来学习如何检查日期交集:
public static bool DateIntersects(DateTime startA, DateTime endA, DateTime startB, DateTime endB)
{
// 在数据库查询中不要忘记以这种方式检查日期!
return startB < endA && startA < endB;
}
由于可以使用IntelliSense探索其他成员,在这里列出了事件;它们很重要,因为它们让能够控制日历的应用。
项目重叠:当项目在日期范围上相交时,有一个不错的算法会执行布局以适应它们。试试看。
项目着色:虽然渲染器负责绘制项目,但可以为项目单独指定背景颜色和边框。更好的是,可以使用CalendarItem中的ApplyColor方法对项目应用颜色,代码将负责为背景、边框和文本着色。
在演示应用程序中,使用日历的上下文菜单为项目应用颜色。
时间刻度:可以选择时间刻度的选项,不过,默认情况下是30分钟,就像Outlook日历一样。这里有一个15分钟时间刻度的示例。
在演示应用程序中,使用日历的上下文菜单选择不同的时间刻度选项。