ASP.NET高级控件——Calendar控件

时间:2023-01-18 18:07:29

Calendar控件编程

Programming the Calendar Control

Calendar控件提供了3个事件,它们并不是从其他控件类继承。通过为事件提供事件处理程序,可以看到日历是如何运行的。这些事件是:

l          SelectionChanged

l          DayRender

l          VisibleMonthChanged

下面详细描述这些事件。

SelectionChanged事件

当用户在Calender控件中选择一天、一周或整个月份时,将触发SelectionChanged事件。以编程方式选择时,并不触发该事件。该事件处理程序传递一个EventArgs类型参数。

接下来的Calendar-SelectionChanged事件说明了如何处理SelectionChanged事件。当选择一个新日期时,它将显示今天的日期、选中的日期及选中的天数。

为了创建该示例,可将上一个示例Calendar-Styles复制为新网站,并命名为Calendar- SelectionChanged。在设计视图中选择Calendar控件,并双击属性窗口的事件图标(闪


电图标),为SelectionChanged事件添加具有默认名称的事件处理程序。

这样,将在内容文件的Calendar控件声明中添加一个OnSelectionChanged属性。同时,打开代码隐藏文件,代码中已经包含了事件处理程序的框架。可以在该方法框架中输入自己的代码。在Calendar1_SelectionChanged方法中输入示例5-18中高亮显示的代码,以及高亮显示的lblCountUpdate辅助方法。

示例5-18Default.aspx.cs from Calendar-SelectionChanged

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

public partial class _Default : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

 

    }

 

    protected void Calendar1_SelectionChanged(object sender, EventArgs e)

    {

       lblTodaysDate.Text = "Today's Date is " +

             Calendar1.TodaysDate.ToShortDateString(  );

 

       if (Calendar1.SelectedDate != DateTime.MinValue)

          lblSelected.Text = "The date selected is " +

             Calendar1.SelectedDate.ToShortDateString(  );

 

       lblCountUpdate(  );

    }

 

   private void lblCountUpdate(  )

   {

      lblCount.Text = "Count of Days Selected:  " +

         Calendar1.SelectedDates.Count.ToString(  );

   }

}

还必须在页面的底部添加3Label控件以便显示日历信息。示例5-19列出了内容文件,其中忽略了Calendar控件的样式属性,因为它们与上一个示例相同。从上一个示例修改的代码已经进行了高亮显示。


示例5-19:从Calendar-SelectionChanged节选的default.aspx.csCalendar样式属性未显示)

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs"

   Inherits="_Default" %>

 

<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.1//EN"

   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Calendar</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

      <h1>Calendar Control</h1>

      <h2>SelectionChanged</h2>

       <asp:Calendar ID="Calendar1" runat="server"

         OnSelectionChanged="Calendar1_SelectionChanged">

       </asp:Calendar>

 

      <br/>

      <asp:Label id="lblCount" runat="server" />

      <br/>

      <asp:Label id="lblTodaysDate" runat="server" />

      <br/>

      <asp:Label id="lblSelected" runat="server" />

    </div>

    </form>

</body>

</html>

运行页面并选择一个日期后,将显示图5-17所示的结果。

在示例5-19中,可以看到该示例为Calendar添加了OnSelectionChanged事件处理程序。该处理程序指向代码隐藏文件中的Calendar1_SelectionChanged方法,如示例5-18所示。在Calendar控件之后添加了3Label控件。第一个Lable控件lblCount,用于显示选择的天数。另外两个Label控件,lblTodaysDatelblSelected,分别用于显示今天的日期和当前选定的日期。

SelectionChanged事件处理方法中,这3Label控件都设置了Text属性。在示例5-18中,可以看到lblTodaysDateCalendar控件的TodaysDate属性填充,使用的代码如下所示:

lblTodaysDate.Text = "Today's Date is " +

   Calendar1.TodaysDate.ToShortDateString(  );


 

5-17:选择日期后的Calendar-SelectionChanged

Calendar控件的IDCalendar1,该控件的TodaysDate属性返回System.DateTime类型的值。为了给Text属性(String类型)赋值,必须把DateTime转换为String。该转换由ToShortDateString方法实现。

DateTime具有多个将DateTime对象转换为其他格式的方法,包括表5-18所显示的方法。

5-18  DateTime转换到字符串的方法

方法名称

 

ToFileTime

转换到本地文件系统的格式

ToLongDateString

转换到长日期字符串

ToLongTimeString

转换到长时间字符串

ToShortTimeString

转换到短时间字符串

ToString

转换到一个字符串

尽管不是ASP.NET特有的,DateTime对于获取日期和时间信息是非常有用的。该结构的一些只读属性在表5-19中列出。


5-19  DateTime的只读属性

属性名称

 

 

Date

DateTime

返回日期部分

Day

Integer

返回月份中的日期

DayOfWeek

DayOfWeek

返回一周中的日期,如FridaySaturday

DayOfYear

Integer

返回年份中的日期

Hour

Integer

返回小时部分

Millisecond

Integer

返回毫秒部分

Minute

Integer

返回分钟部分

Month

Integer

返回月部分

Second

Integer

返回秒部分

Ticks

Long

返回表示日期和时间的以100毫微秒为间隔的间隔数

TimeOfDay

TimeSpan

返回当天的时间

Year

Integer

返回年部分

lblSelected由下面的代码填充:

if (Calendar1.SelectedDate != DateTime.MinValue)

   lblSelected.Text = "The date selected is " +

      Calendar1.SelectedDate.ToShortDateString(  );

为了检查是否选择一日期,可以检测当前选择日期Calendar1.SelectedDate是否等于DateTime.MinValueDateTime.MinValue是一个表示DateTime最小可能值的常量。如果没有选择一个日期SelectedDate属性,则默认为DateTime.MinValueMinValue的值为12:00:00 AM 1/1/0001 CE,还有一个MaxValue字段,它的值为11:59:59 PM12/31/9999 CE

提示:CECommon Era的缩写,它是表示到公历元年的时间间隔的科学符号。BCEBCBefor Christ)的科学表示。

如果用户选择了一个日期,lblSelectedText属性将被设置为SelectedDate属性值的字符串。

Label控件lblCount显示选择的天数。SelectionChanged事件处理程序调用lblCountUpdate方法,该方法设置lblCountText属性。为设置该控件,必须确定选择了多少个日期。Calendar控件有一个SelectedDates属性,它返回一个SelectedDates集合。SelectedDates集合是一个表示Calendar控件所有选定的DateTime对象的集合。CountSelectedDatesCollection对象的一个属性,它返回一个包含集合中日期数量


的整型值。由于Count属性是一个整型值,所以必须使用ToString方法把它转换为一个字符串,才可以给Text属性赋值。

Calendar1.SelectedDates.Count.ToString(  )

尽管SelectedDates(选定日期的集合)和SelectedDate(单个选定的日期)都包含DateTime对象,但只存储Date值,时间值被设置null(在C#语言中)。

SelectedDates集合中的日期是按日期升序排列的。更新SelectedDates集合时,SelectedDate属性自动更新为包含SelectedDates集合的第一个对象。

用户单击月份标题两边的月份导航控件会在月份之间导航。用户也可以单击一天以选中它,单击星期选择控件选定一个星期,单击月份选择控件选中整个月份。

然而,可以给用户更多的灵活性。为此,必须添加几个控件和方法。将当前示例Calendar-SelectionChanged复制到一个新网站,并命名为Calendar-MoreSelections

为使用户可以直接导航到一年中的任意月份,可添加一个包含一年中所有月份的DropDownList和一个标签为TGIF的按钮,该按钮选中当前显示月份所有的星期5

Calendar控件还可以让用户选择一定范围内的日期。您可能希望用户可以使用标准的Windows方法,按住CtrlShift键选择日期的,但这样不行。不过在页面上放几个控件用于选定开始日期和结束日期。在Calendar-MoreSelections中,将添加两个TextBox控件用于输入一定范围内的开始日期和结束日期,以及一个Button控件来强制选择该范围内的日期。

实现该功能的内容文件在示例5-20中列出。同样,为了简洁,所有与Calendar的样式相关的属性都被省略,它们与5-17示例中的相同。从上一个示例修改的代码(它们表示添加的控件)被高亮显示。

示例5-20Calendar-MoreSelectionsDefault.aspx,省略Calendar的样式属性

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs"

   Inherits="_Default" %>

 

<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.1//EN"

   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Calendar</title>

</head>


<body>

    <form id="form1" runat="server">

    <div>

      <h1>Calendar Control</h1>

      <h2>More Selections</h2>

       <asp:Calendar ID="Calendar1" runat="server"

         OnSelectionChanged="Calendar1_SelectionChanged">

       </asp:Calendar>

 

      <br/>

      <asp:Label id="lblCount" runat="server" />

      <br/>

      <asp:Label id="lblTodaysDate" runat="server" />

      <br/>

      <asp:Label id="lblSelected" runat="server" />

      <br/>

      <table>

         <tr>

            <td>

               Select a month:

            </td>

            <td>

               <asp:DropDownList id= "ddl" runat="server"

                  AutoPostBack="true"

                  onSelectedIndexChanged = "ddl_SelectedIndexChanged">

                  <asp:ListItem text="January" value="1" />

                  <asp:ListItem text="February" value="2" />

                  <asp:ListItem text="March" value="3" />

                  <asp:ListItem text="April" value="4" />

                  <asp:ListItem text="May" value="5" />

                  <asp:ListItem text="June" value="6" />

                  <asp:ListItem text="July" value="7" />

                  <asp:ListItem text="August" value="8" />

                  <asp:ListItem text="September" value="9" />

                  <asp:ListItem text="October" value="10" />

                  <asp:ListItem text="November" value="11" />

                  <asp:ListItem text="December" value="12" />

               </asp:DropDownList>

            </td>

            <td>

               <asp:Button id="btnTgif" runat="server"

                  text="TGIF"

                  onClick="btnTgif_Click"/>

            </td>

         </tr>

         <tr>

            <td colspan="2">&nbsp;</td>

         </tr>

         <tr>

            <td colspan="2"><b>Day Range</b></td>

         </tr>


         <tr>

            <td>Starting Day</td>

            <td>Ending Day</td>

         </tr>

         <tr>

            <td>

               <asp:TextBox id= "txtStart" runat="server"

                  Width="25"

                  MaxLength="2" />

            </td>

            <td>

               <asp:TextBox id= "txtEnd" runat="server"

                  Width="25"

                  MaxLength="2" />

            </td>

            <td>

               <asp:Button id="btnRange" runat="server"

                  text="Apply"

                  onClick="btnRange_Click" />

            </td>

         </tr>

      </table>

    </div>

    </form>

</body>

</html>

示例5-21列出了该示例完整的代码隐藏文件。从上一个示例中修改的代码被高亮显示。

示例5-21Calendar-MoreSelectionsDefault.aspx.cs

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

public partial class _Default : System.Web.UI.Page

{

    /// <summary>

    ///  初始化Calendar1 VisibleDate属性和ddl的选定项

    ///  并显示相关信息

    ///  property

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>


    protected void Page_Load(object sender, EventArgs e)

    {

       if (!IsPostBack)

       {

          Calendar1.VisibleDate = Calendar1.TodaysDate;

          ddl.SelectedIndex = Calendar1.VisibleDate.Month - 1;

       }

       lblTodaysDate.Text = "Today's Date is " +

             Calendar1.TodaysDate.ToShortDateString(  );

    }

 

   protected void Calendar1_SelectionChanged(object sender, EventArgs e)

    {

       lblSelectedUpdate(  );

       lblCountUpdate(  );

       txtClear(  );

    }

 

   private void lblSelectedUpdate(  )

   {

      if (Calendar1.SelectedDate != DateTime.MinValue)

         lblSelected.Text = "The date selected is " +

         Calendar1.SelectedDate.ToShortDateString(  );

   }

 

   private void lblCountUpdate(  )

   {

      lblCount.Text = "Count of Days Selected:  " +

         Calendar1.SelectedDates.Count.ToString(  );

   }

 

   protected void ddl_SelectedIndexChanged(Object sender, EventArgs e)

   {

      Calendar1.SelectedDates.Clear(  );

      lblSelectedUpdate(  );

      lblCountUpdate(  );

      Calendar1.VisibleDate = new DateTime(Calendar1.VisibleDate.Year,

                        Int32.Parse(ddl.SelectedItem.Value), 1);

      txtClear(  );

   }

 

   protected void btnTgif_Click(Object sender, EventArgs e)

   {

      int currentMonth = Calendar1.VisibleDate.Month;

      int currentYear = Calendar1.VisibleDate.Year;

 

      Calendar1.SelectedDates.Clear(  );

 

      for (int i = 1;

               i <= System.DateTime.DaysInMonth(currentYear,

                                                currentMonth);

               i++)


      {

         DateTime date = new DateTime(currentYear, currentMonth, i);

         if (date.DayOfWeek == DayOfWeek.Friday)

            Calendar1.SelectedDates.Add(date);

      }

 

      lblSelectedUpdate(  );

      lblCountUpdate(  );

      txtClear(  );

   }

 

   protected void btnRange_Click(Object sender, EventArgs e)

   {

      int currentMonth = Calendar1.VisibleDate.Month;

      int currentYear = Calendar1.VisibleDate.Year;

      DateTime StartDate = new DateTime(currentYear, currentMonth,

                           Int32.Parse(txtStart.Text));

      DateTime EndDate = new DateTime(currentYear, currentMonth,

                         Int32.Parse(txtEnd.Text));

 

      Calendar1.SelectedDates.Clear(  );

      Calendar1.SelectedDates.SelectRange(StartDate, EndDate);

 

      lblSelectedUpdate(  );

      lblCountUpdate(  );

   }

 

   private void txtClear(  )

   {

      txtStart.Text = "";

      txtEnd.Text = "";

   }

}

运行Calendar-MoreSelections,并选择一个日期范围后的结果如图5-18所示。

所有选择控件都位于静态HTML表格中,这样可以控制页面布局。

 

DropDownList控件的ListItem对象包含了作为Text属性的月份名称和作为Value属性的月份数值。

Calendar1_SelectionChanged的大部分代码被重构到一个单独的方法lblSelect- edUpdate中,该方法更新Label控件lblSelectedText属性。这个方法随后被Calendar1_SelectionChanged方法及其他几个方法调用。此外,还有一个辅助方法txtClear,该方法用于清空StartEnd Day文本框。


 

 

5-18:选择一个日期范围后的Calendar-MoreSelections

ddl_SelectedIndexChanged事件处理方法首先清空SelectedDates集合:

Calendar1.SelectedDates.Clear(  );

调用lblSelectedUpdate方法以清空包含第一个选定日期的Label控件,调用lbl- SelectedUpdate方法清空包含选定天数信息的Label控件。然后,Calendar控件的VisibleDate属性设置为新选定月份的第一天:

Calendar1.VisibleDate = new DateTime(Calendar1.VisibleDate.Year,

                  Int32.Parse(ddl.SelectedItem.Value), 1);

VisibleDate属性的类型为DateTime,它初始化了一个新DateTime对象。DateTime结构和.NET Framework中的许多对象一样,使用一个重载的构造函数。该对象可以有不止一个构造函数,每个构造函数都由不同的参数类型或不同的参数个数区分。

因此,需要实例化一个包含该日期的DateTime对象。它需要3个整型参数:yearmonthday。第一个参数是Calendar1.VisibleDate.Year,最后一个参数是1,它本身就是一个整型值。month参数来自DropDownList控件选定项的Value属性。Value属性是个字符串,尽管它包含的字符类似于一个整型值,但并非整型值。因此,它必须被转换为整型值,它使用下面的代码:

Int32.Parse(ddl.SelectedItem.Value)


 

TGIF按钮被命名为btnTgif,并拥有一个Click事件的事件处理程序btnTgif_Click。该方法遍历当前可见月份的每一天,并检测是否是星期五。如果是,则将该日期添加到SelectedDates集合中。

首先,btnTgif_Click方法获取当前可见月的月份和年份,它使用Calendar控件的VisibleDate属性(该属性是一个DateTime对象)来获取这个DateTime对象的MonthYear属性:

int currentMonth = Calendar1.VisibleDate.Month;

int currentYear = Calendar1.VisibleDate.Year;

然后,清空当前所有选择的日期:

Calendar1.SelectedDates.Clear(  );

现在,开始遍历,for循环的限定部分由DateTime对象的DaysInMonth属性决定该月份中的天数。使用的月份由currentYearcurrentMonth两个参数指定:

System.DateTime.DaysInMonth(currentYear, currentMonth)

for循环中,DateTime类型的变量date被赋值为月份中的每一天。同样,该DateTime对象由yearmonthday几个参数实例化。关键的问题来了,这一天是星期五吗?,如果是,则把该日期添加到SelectedDates中:

DateTime date = new DateTime(currentYear, currentMonth, i);

if (date.DayOfWeek == DayOfWeek.Friday)

    cal.SelectedDates.Add(date);

最后,遍历月份的每一天后,调用lblSelectedUpdate方法更新显示第一个选择日期的标签,调用lblCountUpdate方法更新显示选中天数的标签,调用txtClear清空开始和结束日期文本框。

注意代码隐藏文件中的Page_Load方法。如代码中的注释所解释的,它让每一次单击TGIF按钮时,即使在月份变化之前,页面都能正常运行。如果没有Page_Load事件处理程序,则页面只有在月份被更改一次后,才能正常使用TGIF按钮。btnTgif_Click法使用VisibleDate属性设置当前月份和年份变量。如果在页面初始加载时没有初始化该属性,那么赋值到这些变量的值将与可见月份不符。

此外,更新显示今天日期的Label控件lblTodaysDate的代码,由SelectionChanged方法移到了Page_Load方法中,这样,将使lblTodaysDate更敏感,即每次都能正确显示信息。

选择日期范围的控件与选择月份的控件位于同一个静态HTML表格中。其中有两个文本框,txtStart用于开始日期,txtEnd用于结束日期。在这个示例中,TextBox控件


 

WidthMaxLength属性提供了对用户输入的限制。在产品应用程序中,可能需要添加验证控件(在第8章描述),以避免用户输入无效字符或超过一定数量的字符而得到讨厌的错误信息。

CalendarMoreSelections中提供的选择日期范围的用户界面很明显是有限制的,因为,不能跨多个月。可以很容易地提供3个独立的控件:一个用于开始日期、一个用于结束日期、一个用于日期范围。如果在月份更改后不再次应用选择,将无法选定日期范围,因为VisibleMonthChanged并未捕获事件(参考本章后面的“VisibleMonthChanged事件一节)。

txtClear辅助方法用于清空日期范围选择文本框。该方法在其他方法中被调用。

应用按钮命名为btnRangeClick事件处理程序为btnRange_Click。在btnRange_Click中,将当前月份和年份赋值给整型变量:

int currentMonth = Calendar1.VisibleDate.Month;

int currentYear = Calendar1.VisibleDate.Year;

声明两个DateTime变量来保存开始日期和结束日期:

DateTime StartDate = new DateTime(currentYear, currentMonth,

                                  Int32.Parse(txtStart.Text));

DateTime EndDate = new DateTime(currentYear, currentMonth,

Int32.Parse(txtEnd.Text));

与前面描述的月份DropDownList类似,DateTime需要yearmonthday。已经有了整型值的yearmonth,只需要day了。通过把指定文本框的文本转换为整型值可以得到day

提示:这些代码并不是非常健壮。如果用户在其中一个文本框中输入了一个非数字的值,或是大于该月份天数的值,将产生令人讨厌的错误。如果开始日期在结束日期之后,倒不会产生错误,但不会选择任何东西。在实际的应用程序中,需要使用第8章所描述的验证控件。

这个方法获取了DateTime类型的开始日期和结束日期之后,将清除所有当前选择的日期并使用SelectedDatesCollection类的SelectRange方法添加日期范围到Selec- tedDates集合中:

Calendar1.SelectedDates.Clear(  );

Calendar1.SelectedDates.SelectRange(StartDate, EndDate);

SelectRange方法需要两个参数:开始日期和结束日期。


 

DayRender事件

Calendar控件不直接支持日期绑定。然而,可以修改单个日期单元格的内容和格式。这样可从数据库中获取数据,以便进行一些处理后把它们置于指定的单元格中。

Calendar控件呈现到客户端浏览器之前,将组成创建该控件的所有组件。随着创建每个单元格,将引发DayRender事件。可以捕获该事件。

DayRender事件处理程序接收两个DayRenderEventArgs类型的参数。该对象有两个属性,它们可以用编程方式读取:

Cell

表示要呈现的单元格的表格单元格对象。

Day

表示呈现在单元格中日期的CalendarDay对象。

下一个示例Calendar-Events将说明DayRender事件(下面VisibleMonthChanged事件一节将构建同一个示例)。所有的周末将显示不同的背景颜色, 1 1 将显示为元旦。

将上一个示例Calendar-MoreSelections复制为新网站,并命名为Calendar-Events。在这一示例中将捕获DayRender事件。只需要修改两个地方。

首先,在设计视图中选择Canlendar1,单击属性窗口中的事件图标(闪电图标),并双击DayRender旁边的文本框。在内容文件的Calendar1控件声明中添加如下属性:

OnDayRender="Calendar1_DayRender"

该操作同时也将在代码隐藏文件中创建默认的事件处理程序,并将光标置于此以准备输入代码。在该代码框架中输入示例5-22中高亮显示的代码。

示例5-22Calendar-EventsDayRender事件处理程序

protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)

{

   //  注意这将会覆盖WeekendDayStyle

   if (!e.Day.IsOtherMonth && e.Day.IsWeekend)

      e.Cell.BackColor = System.Drawing.Color.LightGreen;

 

   //  在单元格中显示“Happy New Year!”

   if (e.Day.Date.Month == 1 && e.Day.Date.Day == 1)

      e.Cell.Controls.Add(new LiteralControl("<br/>Happy New Year!"));

}


 

Calendar1_DayRender先把周末的颜色设为LightGreen。该控件有一个Weekend- DayStyle属性,它把周末的颜色设为LavenderBlushDayRender方法将覆盖Weekend- DayStyle。(它们之间的差别在纸版图书中可能看不到,但在浏览器中运行该页面时可看到这种差别)。

该事件处理程序传递两个参数:

void DayRender(Object sender, DayRenderEventArgs e)

DayRenderEventArgs包含DayCell的属性。Day用于检测是否在当前月份及是否是周末:

(!e.Day.IsOtherMonth && e.Day.IsWeekend)

Day是一个CalendarDay类型属性。表5-20中列出了CalendarDay类的属性(除Is- Selectable属性之外都是只读的)。

5-20  CalendarDay类的属性

 

 

 

Date

DateTime

Day表示的日期。只读

DayNumberText

String

该日期的日编号的等效字符串。只读

IsOtherMonth

Boolean

指示该日期是否显示当前月份以外的月份。只读

IsSelectable

Boolean

指示该日期是否可以被选择。非只读

IsSelected

Boolean

指示该日期是否被选择

IsToday

Boolean

指示该日期是否是今天

IsWeekend

Boolean

指示该日期是否是周末

如果这个日期既在当前月又是周末,则为Cell.BackColor属性设置一个颜色:

e.Cell.BackColor=System.Drawing.Color.LightGreen;

Calendar1_DayRender方法然后检测选定的日期是否是元旦。同样,使用DayRender- EventArgs对象的Day属性检测日期是否是 1 1

if (e.Day.Date.Month == 1 && e.Day.Date.Day == 1)

如果是 1 1 ,则添加一个Literal控件到单元格中,该控件包含一个换行符和问候语:

e.Cell.Controls.Add(new LiteralControl("<br/>Happy New Year!"));

牢记一点,与所有的ASP.NET服务器控件一样,真正发送到浏览器的是HTML。因此,日历以HTML表格的方式呈现到浏览器。日历上每个可选择的组件都有与之关联的超链接标签,以及完成回发工作的JavaScript(当光标位于可单击的元素上时可以证实这


 

一点:当链接可以单击时,浏览器的状态行将显示要执行的JavaScript函数的名称)。使用LiteralControl控件在HTML单元格中按原样插入文本。查看浏览器源文件中的代码段可以看到下面的内容:

<td align="Center" style="color:Black;background-color:White;

                          font-family:Arial;width:12%;">

    <a href="javascript:_ _doPostBack('cal','selectDay7')" style="color:Black">

    1

    </a>

    <br/>Happy New Year!

</td>

当运行Calendar-Events示例,并导航到一月时,将看到如图5-19所示的页面。

5-19Calendar-Events显示了执行DayRender事件的结果

VisibleMonthChanged事件

Calendar控件还提供了一个事件VisibleMonthChanged以确定用户是否更改了月份。通过扩展当前示例Calendar-Events可以捕获该事件。

使用与添加Calendar1DayRender事件相同的方式,添加VisibleMonthChanged事件的事件处理程序。这将为内容文件的Calendar1声明添加如下属性:

OnVisibleMonthChanged="Calendar1_VisibleMonthChanged">


 

在代码隐藏文件中,创建默认事件处理程序代码结构,并将光标置于此以准备输入代码。在这个代码结构中输入示例5-23中高亮显示的代码。

示例5-23Calendar-Events中的VisibleMonthChanged事件处理程序

protected void Calendar1_VisibleMonthChanged(object sender,

                                             MonthChangedEventArgs e)

{

   if ((e.NewDate.Year > e.PreviousDate.Year) ||

      ((e.NewDate.Year == e.PreviousDate.Year) &&

      (e.NewDate.Month > e.PreviousDate.Month)))

      lblMonthChanged.Text = "My future's so bright...";

   else

      lblMonthChanged.Text = "Back to the future!";

 

   Calendar1.SelectedDates.Clear(  );

   lblSelectedUpdate(  );

   lblCountUpdate(  );

   txtClear(  );

}

还需要在内容文件中的Calendar控件前面添加一个Label控件,并命名为lblMon- thChanged

<asp:Label id="lblMonthChanged" runat="server" />

Calendar1_VisibleMonthChanged事件处理程序接收一个MonthChangedEventArgs类型的参数。该参数包含两个从程序读取的属性:

NewDate

表示Calendar当前显示的月份。

PreviousDate

表示Calendar以前显示的月份。

Calendar1_VisibleMonthChanged方法中,检测这些值哪一个更早。根据检测结果,两个字符串之一将赋给lblMonthChangedText属性。

最后,使用如下代码清除从日历选择的日期、更新日历下面的文本字符串、清除日期范围编辑框的内容:

Calendar1.SelectedDates.Clear(  )

lblSelectedUpdate(  )

lblCountUpdate(  )

txtClear(  )

运行Calendar-Events并导航到一个月份后,结果如图5-20所示。


 

 

5-20:触发VisibleMonthChanged事件后的VisibleMonthChanged