ASP.NET笔记之Calendar的使用说明
ASP.NET Web Forms 中的 Calendar 控件是一个功能强大的内置服务器控件,专门用于在Web页面上呈现交互式日历,方便用户直观地查看和选择日期,它简化了日期选择功能的实现,无需依赖复杂的JavaScript库。

Calendar基础使用与核心属性
-
添加到页面
在ASP.NET Web Forms页面(.aspx)中,可以通过工具箱拖放或手动添加标签来使用Calendar控件:<asp:Calendar ID="Calendar1" runat="server" OnSelectionChanged="Calendar1_SelectionChanged"></asp:Calendar>
-
关键属性
SelectedDate: 获取或设置用户选中的日期(DateTime类型),初始设置此属性可预选日期。VisibleDate: 获取或设置控件当前显示的月份(DateTime类型),设置此属性可控制日历初始展示哪个月份,而不影响选中日期。SelectionMode: 决定用户可选择日期的范围:Day(默认): 选择单个日期。DayWeek: 选择单个日期或整周(点击周选择器)。DayWeekMonth: 选择单个日期、整周或整月(点击月选择器)。None: 不可选择(仅用于显示)。
TodaysDate: 获取或设置被视为“的日期(DateTime类型),通常用于高亮显示当前日,默认为服务器日期。ShowDayHeader: 是否显示星期几的表头(如“日”、“一”…“六”)。ShowNextPrevMonth: 是否显示用于导航到上/下个月的链接(<和>)。ShowTitle: 是否显示包含月份名称和年份的标题栏。TitleFormat: 标题栏的显示格式(MonthYear或Month)。DayNameFormat: 星期几表头的显示格式(如Full,Short,FirstLetter,FirstTwoLetters,Shortest)。FirstDayOfWeek: 设置日历每周的第一天(Sunday,Monday)。
处理用户交互 – 事件
-
SelectionChanged: 最常用的事件,当用户选择新的日期(或周、月)时触发,需要在服务器端编写事件处理方法:protected void Calendar1_SelectionChanged(object sender, EventArgs e) { // 获取选中的日期 DateTime selectedDate = Calendar1.SelectedDate; // 获取选中的日期集合(当SelectionMode为DayWeek/DayWeekMonth时可能有多个) SelectedDatesCollection selectedDates = Calendar1.SelectedDates; // 根据选中日期执行操作,例如更新标签、筛选数据等 lblSelectedDate.Text = "您选择的日期是: " + selectedDate.ToShortDateString(); } -
VisibleMonthChanged: 当用户点击上/下月导航按钮改变当前显示的月份时触发。
protected void Calendar1_VisibleMonthChanged(object sender, MonthChangedEventArgs e) { // e.NewDate 是改变后显示的新月份 // e.PreviousDate 是改变前显示的月份 // 可以在此根据新月份加载相关数据 } -
DayRender: 极其重要且强大的事件,在日历呈现到页面之前,为每一个要渲染的日期单元格(CalendarDay)触发,允许你:-
动态修改单元格内容: 添加文字、链接、图片或其他控件。
-
自定义日期样式: 基于业务逻辑(如周末、节假日、数据库中有事件的日期)设置单元格的前景色、背景色、字体、是否可选等。
-
禁用特定日期: 将
CalendarDay.IsSelectable设置为false。protected void Calendar1_DayRender(object sender, DayRenderEventArgs e) { // 获取当前正在渲染的日期信息 DateTime date = e.Day.Date; CalendarDay day = e.Day; // 示例1: 禁用周末选择 if (day.IsWeekend) { day.IsSelectable = false; // 禁用选择 e.Cell.BackColor = System.Drawing.Color.LightGray; // 设置背景色 } // 示例2: 高亮显示特定日期(如今天) if (date.Date == DateTime.Today.Date) { e.Cell.BackColor = System.Drawing.Color.Yellow; } // 示例3: 根据数据库动态添加事件标记 (伪代码) if (YourDataHelper.HasEventOnDate(date)) { e.Cell.Controls.Add(new LiteralControl("<br /><span style='color:red;font-size:smaller;'>有活动</span>")); } // 示例4: 完全自定义内容 if (date.Day == 1) // 每月1号 { e.Cell.Controls.Clear(); // 清除默认内容 e.Cell.Controls.Add(new LiteralControl("<strong>" + date.Day.ToString() + "</strong><br />New Month!")); } }
-
样式美化
- 使用内置样式属性: Calendar 提供了大量以
...Style结尾的属性(如DayStyle,WeekendDayStyle,SelectedDayStyle,TodayDayStyle,OtherMonthDayStyle,TitleStyle,NextPrevStyle,DayHeaderStyle)来设置不同部分的外观。<asp:Calendar ID="Calendar1" runat="server"> <DayStyle BackColor="#FFFFFF" ForeColor="#000000" /> <WeekendDayStyle BackColor="#F0F0F0" Font-Italic="true" /> <SelectedDayStyle BackColor="#FF9900" Font-Bold="true" /> <TodayDayStyle BackColor="#FFFFCC" BorderWidth="1px" BorderColor="#CCCCCC" /> <OtherMonthDayStyle ForeColor="#CCCCCC" /> <TitleStyle BackColor="#333333" ForeColor="White" Font-Bold="true" /> <NextPrevStyle ForeColor="White" /> <DayHeaderStyle BackColor="#CCCCCC" Font-Bold="true" /> </asp:Calendar> - 使用CSS类: 更推荐的方式是为各个样式属性指定
CssClass,然后在外部CSS文件中定义样式规则,实现样式与代码分离,便于维护和主题切换。<asp:Calendar ID="Calendar1" runat="server"> <DayStyle CssClass="cal-day" /> <SelectedDayStyle CssClass="cal-selected" /> ...其他样式... </asp:Calendar>.cal-day { background-color: white; color: black; } .cal-selected { background-color: #FF9900; font-weight: bold; } / 为DayRender中动态添加的元素定义样式 / .event-marker { color: red; font-size: smaller; display: block; }
进阶技巧与最佳实践

- 动态数据绑定与DayRender:
DayRender事件是实现日历与动态数据(如日程、任务、数据库记录)关联的核心,在事件处理程序中,根据当前渲染的日期(e.Day.Date)查询数据源,并动态修改单元格内容和样式。 - 日期范围限制: 结合
DayRender事件,通过设置e.Day.IsSelectable = false来实现禁用过去日期、未来日期或特定日期(如节假日、不可用日期)。 - 处理时区: 如果应用涉及多时区用户,要特别注意服务器日期(
DateTime.Now)和用户本地日期的转换。Calendar控件本身不处理时区,通常需要结合用户配置或JavaScript获取的时区信息在服务器端进行转换,将TodaysDate设置为UTC日期或转换后的用户本地日期是一种常见做法。 - 性能考虑:
DayRender事件对每个可见的日期单元格都会触发一次,如果在该事件中进行复杂的数据库查询或计算,可能会影响页面渲染性能,务必优化查询(如批量获取整个月份的数据并缓存),避免在DayRender中执行过于耗时的操作。 - ViewState: Calendar 控件默认启用 ViewState 来保存其状态(如
SelectedDate,VisibleDate),如果页面不需要保留这些状态或对性能要求极高,可以考虑在特定场景下设置EnableViewState="false",但需要自行管理状态(例如在每次回发后根据需要重新设置SelectedDate和VisibleDate)。
常见场景与替代方案
- 简单日期选择:
Calendar控件是最直接的内置选择。 - 复杂日期关联展示(如日程表):
Calendar+DayRender事件是经典组合。 - 更现代/轻量级的UI: ASP.NET Web Forms 内置的
Calendar控件样式可能略显陈旧,对于追求更现代外观和用户体验的项目,可以考虑:- HTML5
<input type="date">: 简单易用,浏览器原生支持,但样式定制性有限,兼容性需注意。 - 第三方JavaScript日历库: 如 Bootstrap Datepicker, Flatpickr, Pikaday 等,这些库通常功能强大、样式美观、可定制性高,需要通过
TextBox控件结合JavaScript进行集成,并在服务器端获取TextBox.Text的值,这是目前非常主流的做法。 - ASP.NET AJAX Control Toolkit CalendarExtender: 为
TextBox提供弹出式日历,比原生Calendar控件更轻量、集成度更好,但依赖于 AJAX Control Toolkit。
- HTML5
ASP.NET Web Forms 的 Calendar 控件提供了一个开箱即用的服务器端解决方案,用于在Web页面中集成交互式日历功能,其核心价值在于通过 SelectionChanged 事件处理用户日期选择,以及通过强大的 DayRender 事件实现高度的日期单元格内容与样式定制化,非常适合需要将日期与后端业务逻辑(如日程、事件、任务)紧密关联的场景,虽然其原生样式可能不如现代JS库炫丽,但通过CSS样式属性和 CssClass 可以大幅改善外观,对于追求极致现代UI或轻量级的简单日期选择,评估第三方JS库或HTML5输入类型通常是更优的选择,理解 Calendar 的属性、事件(尤其是 DayRender)和样式机制,是有效利用该控件的关键。
你在项目中使用 Calendar 控件时,遇到最棘手的挑战是什么?是日期动态渲染的性能优化、复杂的样式定制,还是与特定日期选择逻辑相关的难题?或者你更倾向于使用哪些第三方日历库?欢迎分享你的实战经验和看法!
原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/7154.html