AsyncCalendar 教程,终极日历。






2.60/5 (4投票s)
2006 年 11 月 17 日
7分钟阅读

27876
介绍如何轻松实现一个 AsyncCalendar,它可以渲染日历的任何控件,并从渲染的控件中获取事件。
引言
本文将介绍如何使用和实现 AsyncCalendar(来自备受期待的 AsyncControls Suite)。与其他 AsyncControls 一样,AsyncCalendar 支持 AJAX,并具有 asp:Calendar 或其他日历控件所不具备的许多增强功能。AsyncCalendar 能够渲染并接收来自任何 AsyncControls 的事件。 任何 AsyncDay 都可以渲染超过 30 种 AsyncControls 中的任何一种。这意味着您可以真正地将 AsyncPageRepeater、AsyncSuggestBox 或 AsyncUserControl 嵌套在 AsyncDay 中。此外,它还拥有比其他 AsyncControls 更多的属性,因此也具有最大的灵活性。它模仿了 AsyncPageRepeater 和 AsyncUserControl 的行为。除了 AsyncCalendar 的众多功能外,只需设置三个属性,它现在就可以用作“弹出”日历控件。
AsyncCalendar 不仅提供日期输入功能,还提供无限的渲染功能。我将尝试介绍利用这些功能的最常见方法。
实现 AsyncCalendar(标准模式)
AsyncCalendar 默认使用标准模式渲染。此模式允许将日历像其他控件一样放置在页面上。它提供了一种更“开放”的布局。在标准模式下使用日历可以解除尺寸限制。
实现 AsyncCalendar(标准模式)
1.) 如果您页面上已有 asp:Calendar
- 只需将其重命名为 AsyncCalendar 即可。幸运的是,AsyncCalendar 支持大多数常用属性。
2.) 如果您从头开始创建日历
ASPX
<dw:AsyncCalendar runat="server" ID="asyncCal" Width="600" AbbreviateDays="false" DefaultStyle="false" YearListCssClass="calYearList" MonthListCssClass="calMonthList" YearSelectorCssClass="calYearSel" MonthSelectorCssClass="calMonthSel" CssClass="asynccal" DayCssClass="calday" WeekendDayCssClass="weekendcal" OtherMonthCssClass="othermonthcal" ShowGridLines="false" ShowTodayFooter="true" PreviousMonthText="<<" NextMonthText=">>" OnDayRender="cal_DayRender" OnDaySelected="cal_DaySelected" SelectedDayCssClass="selDay" ShowOnTextClick="true" IsIconic="false" AssociatedTextBox="calTxt" IconImageUrl="images/calicon.jpg"> <dw:AsyncDay runat="server" ID="day1"> <div align="right"><dw:AsyncLiteral runat="server" ID="calLtlDate" /></div> <span style="font-size: 9px;"> Users scheduled for today. </span> <dw:AsyncPageRepeater runat="server" ID="calRpt" CssClass="calRpt" PagingComponentCssClass="calRptPaging" RangeOfTextFormat="" RangeCurrentPageTextFormat="<b><{0}></b>" PageSize="3" MaxItemCount="10" OnItemDataBound="calRpt_ItemDataBound" NextPageComponentText="" PreviousPageComponentText=""> <HeaderTemplate> <table> </HeaderTemplate> <ItemTemplate> <tr> <td><span style="font-size: 10px;"><img src="images/misc/ac_user.jpg" /><dw:AsyncLiteral runat="server" ID="calRptLtl" /></span></td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </dw:AsyncPageRepeater> </dw:AsyncDay> </dw:AsyncCalendar>
代码隐藏 (CS)
protected void cal_DayRender( object sender, AsyncDayRenderEventArgs ae )
{
if ( ae.IsToday )
{
calLtlDate.Text = ae.DayNumberText;
calRpt.DataBind(GetUsers());
ae.Day = day1;
}
if ( ae.Date.DayOfWeek == DayOfWeek.Wednesday && !ae.IsOtherMonth )
{
Control c = this.LoadControl("~/Controls/CalendarUserControl.ascx");
AsyncDay day = new AsyncDay();
day.ID = "tempDay";
c.ID = "tempID";
day.Controls.Add(c);
ae.Day = day;
}
// hide the other days
if ( ae.IsOtherMonth )
{
ae.Html = " ";
}
}
实现 AsyncCalendar(图标模式)
<dw:AsyncTextBox runat="server" ID="calTxt" /> <dw:AsyncCalendar runat="server" ID="tinyAsyncCal" AbbreviateDays="true" AbbreviateMonths="true" ShowGridLines="false" ShowTodayFooter="true" PreviousMonthText="<<" NextMonthText=">>" TodayCssClass="selDay" ShowOnTextClick="true" VisibleDateFromTextBox="true" IsIconic="true" AssociatedTextBox="calTxt" IconImageUrl="images/calicon.jpg" YearListCssClass="calYearList" MonthListCssClass="calMonthList" YearSelectorCssClass="calYearSel" MonthSelectorCssClass="calMonthSel" TodayFooterCssClass="calTodayFooter" CssClass="iconCal" DayCssClass="iconCalDay" OtherMonthCssClass="iconCalOtherMonth" WeekendDayCssClass="iconCalWeekend" DefaultStyle="false" />AsyncCalendar 还允许您快速轻松地为 AsyncRepeater 中的文本框或页面上的文本框实现日期输入。
要在图标模式下实现 AsyncCalendar,请将 AsynCalendar.IsIconic 设置为 true,将 AsyncCalendar.IconImageUrl 设置为目标图片,或将 AsyncCalendar.IconText 设置为所需的显示文本。最后,将 AsyncCalendar.AssociatedTextBox 设置为您希望显示所选日期的 AsyncTextBox 的 ID。
此模式将强制 AsyncCalendar 初始隐藏,然后在激活时,它会浮动在 IconText 或 IconImageUrl 显示的图片附近。用户可以通过单击 AssociatedTextBox、IconText 或图标图片来激活 AsyncCalendar。AsyncCalendar 还可以显示用户输入的日期。因此,如果用户输入了一个日期并激活了日历,它将“跳转”到指定的日期。无需验证。
在此模式下,AsyncCalendar 仍然是完全可自定义的。因此,您可以通过代码更改在标准模式和图标模式之间轻松切换。
AsyncCalendar 说明
根据日历的用途或目标,您可能需要利用 AsyncCalendar 提供的其他属性或方法。不幸的是,我不知道您的意图,因此无法将此部分针对特定场景,但我可以描述您可能认为最有用的属性和方法。
1.) “Weekday Text”属性非常有用,如果您想自定义日历的星期几显示文本。如果 AsyncCalendar.AbbreviateDays 不符合您的需求,您可以为一周中的每一天设置文本。您可以将 FridayText 设置为“HappyDay”,将 MondayText 设置为“StartDay”,或者任何您想要的。每一天都可以有自己的文本。一个常见的用途可能是通过只显示星期几的首字母来最大化日文本的显示空间。
2.) “Month Text”属性允许您自定义公历中每个月的月份文本显示。如果 AsyncCalendar.AbbreviateMonths 不符合您的需求,您可以将 AugustText 设置为“GreatMonth”,将 SeptemberText 设置为“Sept.”。每个月都可以有自己的文本显示。
3.) SelectionMode,如果设置为“Multiple”,则允许用户在日历上选择多个日期。如果设置了 SelectedDayCssClass,它还会更改相应日期的 CSS 类。使用 AsyncCalendar.SelectedDates 获取用户选择的日期。
4.) “Month and Year Selectors”(在标准和图标模式下均可用)可以完全自定义或删除。设置 Show*Selector 可以隐藏/显示月份或年份选择器。使用 *SelectorCssClass 为月份或年份选择器分配 CSS 类。
5.) 使用 Show* 方法可以以编程方式“跳转”到不同的日期。您可以使用 ShowNextMonth()、ShowPreviousMonth()、ShowToday() 以及您喜爱的 ShowDate(DateTime)。这些当然是 Async-Enabled 的,可以在 AsyncCallback 中使用。
UpdateCalendar() 的使用有点高级。由于并非所有对日历的更改都支持 Async,您可能需要“强制”日历将更改渲染到客户端。例如,如果您在 AsyncCallback 中修改了 SelectedDates 集合;或者如果您设置了 AsyncCalendar.VisibleDate(因为您选择不使用 ShowDate(DateTime)),则应调用此方法。
请记住,AsyncCalendar(以及一些 AsyncControls)会渲染其默认样式,除非将 DefaultStyle 设置为 false。
使用 AsyncCalendar 事件
1.) CalendarChanged,当用户从选择器中选择月份或年份,或者使用上个月和下个月导航时发生。
2.) DayMouseOver,当用户的鼠标移入 AsyncDay 的边界时发生。
3.) DayMouseOut,当用户的鼠标移出 AsyncDay 的边界时发生。
4.) DaySelected,当用户单击或选择 AsyncDay 时发生。
5.) DayRender,当 AsyncDay 正在渲染时发生。
如果您通过分配 AsyncDay 或设置 HTML 来更改 AsyncDay,则 DayMouseOver、DayMouseOut 和 DaySelected 事件将不会发生。
AsyncCalendar.DayRender 事件
此事件需要一个单独的部分,因为它是一个最复杂和最先进的事件之一。
DayRender 在日历外观方面非常非常强大。根据您渲染到 AsyncDay 的内容,可能会影响 AsyncCalendar 的性能。通过默认渲染,底层服务器仍然几乎即时地将日历渲染给用户。每次更改月份/年份都会尽快反映给用户。这对您来说是一个明确的优势,因为您不是从一个缓慢的引擎开始的。关于 AsyncUserControls 及其简化 AsyncDays 创建的能力,我建议使用它们。但您也可以使用任何您想要的 AsyncControl。
AsyncDay 本身就是一个标签/类。您可以在前端使用它,或者在代码隐藏中创建一个实例,并动态地向其添加控件。
实现 AsyncDay
如果您选择动态创建 AsyncDay(代码隐藏)您还必须将其显式添加到相应的 AsyncCalendar(别忘了添加子控件)。您可以通过将 AsyncDayRenderEventArgs.Day 设置为您创建的实例来做到这一点。
示例(在 DayRender 事件期间)
// create the user control to be added to the AsyncDay
Control userCtrl = this.LoadControl("~/Controls/CalendarUserControl.ascx");
// create a new AsyncDay
AsyncDay newDay = new AsyncDay();
// assign IDs
newDay.ID = "tempDay";
userCtrl.ID = "tempID";
// add the user control
newDay.Controls.Add(userCrtl);
// then assign the created AsyncDay to the day being rendered
asyncDayRenderEventArgs.Day = newDay;
如果您选择创建静态 AsyncDay(前端)
<dw:AsyncDay runat="server" ID="staticDay1" Date="8/13/2007"> <!-- AsyncControls I want to be rendered on this day --> <dw:AsyncDay>您只需像使用任何其他 AsyncPanel 一样使用 AsyncDay,将所有子控件放置在 AsyncDay 内部区域。您可能希望将 AsyncDay.Date 设置为相关日期,并且在 DayRender 期间,AsyncDay 将为您渲染。前端设置的日期将保留,因此如果您将 AsyncDay 分配给另一个日期,它仍将在两个日期上渲染。
请记住,将其他 AsyncCalendars 甚至整个网页放入 AsyncDay 可能不是一个好主意,别忘了用户必须下载所有这些内容。