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

一款专业的日历/日程视图,您一定会用

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (340投票s)

2009年8月3日

LGPL3

5分钟阅读

viewsIcon

3419239

downloadIcon

117720

Outlook 风格的日历视图,包含约会和全天事件,并支持多日视图。

引言

正如您在截图中所见,这是一个功能齐全的日历视图,用于指定约会和全天事件。它具有多种功能,可让您控制内部事件,例如项目阻塞和面向项目的事件。

它是 100% 受管代码!没有资源;与我的大多数项目一样,您可以将所有源文件包含到您的项目中即可运行。

背景

我找到过几个类似的控件,但一如既往,它们不符合我的需求,所以我自己动手了。它的性能相当不错,但很大程度上取决于您的实现——我将在下一节中对此进行解释。

Using the Code

要将日历添加到您的窗体,只需拖动 Calendar 控件即可。它位于 System.Widows.Forms.Calendar 命名空间下。

何时使用

它可以用于显示任何基于日期的信息,不仅仅是约会和会议。想想看,您将在哪个糟糕的控件上显示您的系统日志?

控制视图

Calendar 的视图由 ViewStartViewEnd 属性提供的日期范围决定。根据这两个日期之间的天数,日历将绘制它们。

Calendar 可以显示两种模式的天:Expanded(展开)和 Short(简略)(参见 Calendar.DaysMode)。Expanded 模式是第一个截图的样式:日期显示在列中,事件放置在它们所属的时间;而 Short 模式(第二个截图)将日期显示在周行中,事件显示得更紧凑。

这里的一个重要属性是 MaximumFullDays(默认为 8)。此属性表示当您指定 8 天或更少的视图时,日期将以 Expanded 模式显示。任何更多天数将以 Short 模式显示。

向日历填充项目

日历通过 LoadItems 事件通知您何时向其中添加项目。在该事件中,您应该通过将项目添加到日历的 Items 集合中来管理显示在日历中的信息。每次视图更改时都会引发此事件。我强烈建议您使用缓存,而不是每次引发此事件时都查询数据库,因为这会严重影响性能。

源代码中的演示项目从内存数组加载项目,因此不是最佳示例。

private void calendar1_LoadItems(object sender, CalendarLoadEventArgs e)
{
    //Load items whose date range intersects e.DateStart and e.DateEnd
    foreach(CalendarItem item in loadedItems)
    {
         calendar1.Items.Add(item);
    }
 
    //Or even better....
    calendar1.Items.AddRange(loadedItems);
}

我强烈建议只添加与日历视图范围相交的项目。您可以查看 Calendar 中的 DateIntersects 实现来了解如何检查日期相交。

public static bool DateIntersects(DateTime startA, DateTime endA, 
                                  DateTime startB, DateTime endB)
{
     //Don't forget to check dates this way in your database queries!
     return startB < endA && startA < endB;
}

事件

由于您可以使用 IntelliSense 探索其他成员,因此我在此列出事件;它们很重要,因为它们可以让您控制 Calendar 的应用程序。

  • DayHeaderClick:单击日期标题时发生。
  • ItemClick:单击项目时发生。
  • ItemCreated:成功创建项目时发生。
  • ItemCreating:用户即将创建项目时发生。可以取消。
  • ItemDatesChanged:项目日期范围更改时发生。
  • ItemDeleted:成功删除项目时发生。
  • ItemDeleting:用户即将删除项目时发生。可以取消。
  • ItemDoubleClick:双击项目时发生。
  • ItemMouseHover:鼠标悬停在项目上时发生。
  • ItemSelected:选择项目时发生。
  • ItemTextEdited:用户编辑项目文本时发生。
  • ItemTextEditing:用户尝试编辑项目文本时发生。可以取消。
  • LoadItems:更改日历视图时发生。

一些不错的功能

项目重叠

当项目在日期范围内重叠时,有一个很好的算法可以对其进行布局以容纳它们。试试吧。

项目着色

尽管渲染器负责绘制项目,但您可以单独指定项目的背景颜色和边框。

更好的是,您可以使用 CalendarItem 中的 ApplyColor 方法为项目应用颜色,代码将负责着色背景、边框和文本。

在演示应用程序中,使用日历的上下文菜单为项目应用着色。

时间刻度

您可以选择时间刻度的选项,尽管默认是 30 分钟,类似于 Outlook 的日历。这里是 15 分钟时间刻度的示例。

在演示应用程序中,使用日历的上下文菜单选择不同的时间刻度选项。

MonthViewControl

您是否非常讨厌 MonthCalendar 控件在您 UI 上的表现?那么,这里是解决方案。现在,该项目包含一个名为 MonthView 的控件,它看起来像 Outlook 日历的视图,完全可自定义,并且不强制控件的大小;月份的可视化将取决于容器的大小。

该控件的一些有趣属性是

  • FirstDayOfWeek - 更改您的星期从哪一天开始。
  • ItemPadding - 设置内部项目的填充,因此您可以创建紧凑或不太紧凑的视图。
  • SelectionMode - Manual(手动)、Day(日)、Week(周)、WorkWeek(工作周)和 Month(月)。
  • WorkWeekStart - 指定工作周从哪一天开始。
  • WorkWeekEnd - 指定工作周在哪一天结束。

历史

  • 2009 年 8 月 2 日:首次发布。
  • 2009 年 8 月 5 日
    • 许可证更改为 LGPL。
    • 添加了 FirstDayOfWeek 属性以更改您的星期从哪一天开始。
    • CalendarItem 添加了 Tag 属性。
  • 2009 年 8 月 27 日
    • 添加了分钟精确指示。
    • 添加了键盘箭头支持。
    • CalendarItem 添加了 ImageImageAlign 属性,用于向项目中添加图像。
    • CalendarItem 添加了 PatternPatternColor 属性,用于用纹理标记项目。
    • 添加了 MonthView 控件,以获得一个漂亮的日历控件。
© . All rights reserved.