2 // System.Web.UI.WebControls.Calendar.cs
5 // Jordi Mas i Hernandez (jordi@ximian.com)
7 // (C) 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Globalization;
33 using System.Collections;
34 using System.ComponentModel;
37 namespace System.Web.UI.WebControls {
38 [DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + Consts.AssemblySystem_Design)]
39 [DefaultEvent("SelectionChanged")]
40 [DefaultProperty("SelectedDate")]
41 [Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
43 [ControlValueProperty ("SelectedDate", "1/1/0001 12:00:00 AM")]
45 public class Calendar : WebControl, IPostBackEventHandler {
47 private TableItemStyle dayHeaderStyle;
48 private TableItemStyle dayStyle;
49 private TableItemStyle nextPrevStyle;
50 private TableItemStyle otherMonthDayStyle;
51 private TableItemStyle selectedDayStyle;
52 private TableItemStyle titleStyle;
53 private TableItemStyle todayDayStyle;
54 private TableItemStyle selectorStyle;
55 private TableItemStyle weekendDayStyle;
56 private DateTimeFormatInfo dateInfo;
57 private SelectedDatesCollection selectedDatesCollection;
58 private ArrayList dateList;
59 private static DateTime dateZenith = new DateTime (2000, 1,1);
60 private const int daysInAWeek = 7;
61 private static readonly object DayRenderEvent = new object ();
62 private static readonly object SelectionChangedEvent = new object ();
63 private static readonly object VisibleMonthChangedEvent = new object ();
67 dateInfo = new DateTimeFormatInfo ();
73 [WebSysDescription ("")]
74 [WebCategoryAttribute ("Appearance")]
75 public virtual string Caption
78 return ViewState.GetString ("Caption", "");
81 ViewState["Caption"] = value;
85 [DefaultValue (TableCaptionAlign.NotSet)]
86 [WebSysDescription ("")]
87 [WebCategoryAttribute ("Accessibility")]
88 public virtual TableCaptionAlign CaptionAlign
91 return (TableCaptionAlign)ViewState.GetInt ("CaptionAlign", (int)TableCaptionAlign.NotSet);
94 ViewState ["CaptionAlign"] = value;
103 [WebSysDescription ("")]
104 [WebCategory ("Layout")]
105 public int CellPadding {
107 return ViewState.GetInt ("CellPadding", 2);
112 throw new ArgumentOutOfRangeException ("The specified cell padding is less than -1.");
114 ViewState ["CellPadding"] = value;
122 [WebSysDescription ("")]
123 [WebCategory ("Layout")]
124 public int CellSpacing {
126 return ViewState.GetInt ("CellSpacing", 0);
131 throw new ArgumentOutOfRangeException ("The specified cell spacing is less than -1");
133 ViewState ["CellSpacing"] = value;
137 [PersistenceMode(PersistenceMode.InnerProperty)]
138 [NotifyParentProperty(true)]
139 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
140 [WebSysDescription ("")]
141 [WebCategory ("Style")]
142 public TableItemStyle DayHeaderStyle {
144 if (dayHeaderStyle == null) {
145 dayHeaderStyle = new TableItemStyle ();
146 if (IsTrackingViewState)
147 dayHeaderStyle.TrackViewState ();
150 return dayHeaderStyle;
157 [DefaultValue(DayNameFormat.Short)]
158 [WebSysDescription ("")]
159 [WebCategory ("Appearance")]
160 public DayNameFormat DayNameFormat {
162 return (DayNameFormat) ViewState.GetInt ("DayNameFormat", (int) DayNameFormat.Short);
166 if (value != DayNameFormat.FirstLetter && value != DayNameFormat.FirstTwoLetters &&
167 value != DayNameFormat.Full && value != DayNameFormat.Short) {
168 throw new ArgumentOutOfRangeException ("The specified day name format is not one of the DayNameFormat values.");
171 ViewState ["DayNameFormat"] = value;
176 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
177 [NotifyParentProperty(true)]
178 [PersistenceMode(PersistenceMode.InnerProperty)]
179 [WebSysDescription ("")]
180 [WebCategory ("Style")]
181 public TableItemStyle DayStyle {
183 if (dayStyle == null) {
184 dayStyle = new TableItemStyle ();
185 if (IsTrackingViewState)
186 dayStyle.TrackViewState ();
196 [DefaultValue(FirstDayOfWeek.Default)]
197 [WebSysDescription ("")]
198 [WebCategory ("Appearance")]
199 public FirstDayOfWeek FirstDayOfWeek {
201 return (FirstDayOfWeek) ViewState.GetInt ("FirstDayOfWeek", (int) FirstDayOfWeek.Default);
205 if (value < FirstDayOfWeek.Sunday || value > FirstDayOfWeek.Default) {
206 throw new ArgumentOutOfRangeException ("The specified day name format is not one of the DayNameFormat values.");
209 ViewState ["FirstDayOfWeek"] = value;
216 [DefaultValue(">")]
220 [WebSysDescription ("")]
221 [WebCategory ("Appearance")]
222 public string NextMonthText {
224 return ViewState.GetString ("NextMonthText", ">");
228 ViewState ["NextMonthText"] = value;
235 [DefaultValue(NextPrevFormat.CustomText)]
236 [WebSysDescription ("")]
237 [WebCategory ("Appearance")]
238 public NextPrevFormat NextPrevFormat {
240 return (NextPrevFormat) ViewState.GetInt ("NextPrevFormat", (int) NextPrevFormat.CustomText);
244 if (value != NextPrevFormat.CustomText && value != NextPrevFormat.ShortMonth && value != NextPrevFormat.FullMonth) {
245 throw new ArgumentOutOfRangeException ("The specified day name format is not one of the DayNameFormat values.");
248 ViewState ["NextPrevFormat"] = value;
252 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
253 [NotifyParentProperty(true)]
254 [PersistenceMode(PersistenceMode.InnerProperty)]
255 [WebSysDescription ("")]
256 [WebCategory ("Style")]
257 public TableItemStyle NextPrevStyle {
259 if (nextPrevStyle == null) {
260 nextPrevStyle = new TableItemStyle ();
261 if (IsTrackingViewState)
262 nextPrevStyle.TrackViewState ();
265 return nextPrevStyle;
270 [NotifyParentProperty(true)]
271 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
272 [PersistenceMode(PersistenceMode.InnerProperty)]
273 [WebSysDescription ("")]
274 [WebCategory ("Style")]
275 public TableItemStyle OtherMonthDayStyle {
277 if (otherMonthDayStyle == null) {
278 otherMonthDayStyle = new TableItemStyle ();
279 if (IsTrackingViewState)
280 otherMonthDayStyle.TrackViewState ();
283 return otherMonthDayStyle;
290 [DefaultValue("<")]
294 [WebSysDescription ("")]
295 [WebCategory ("Appearance")]
296 public string PrevMonthText {
298 return ViewState.GetString ("PrevMonthText", "<");
302 ViewState ["PrevMonthText"] = value;
307 [Bindable(true, BindingDirection.TwoWay)]
311 [DefaultValue("1/1/0001 12:00:00 AM")]
312 [WebSysDescription ("")]
313 [WebCategory ("Appearance")]
314 public DateTime SelectedDate {
316 if (SelectedDates.Count > 0)
317 return SelectedDates [0];
319 return DateTime.MinValue;
323 SelectedDates.SelectRange (value, value);
328 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
329 [WebSysDescription ("")]
330 [WebCategory ("Appearance")]
331 public SelectedDatesCollection SelectedDates {
333 if (dateList == null)
334 dateList = new ArrayList ();
336 if (selectedDatesCollection == null)
337 selectedDatesCollection = new SelectedDatesCollection (dateList);
339 return selectedDatesCollection;
344 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
345 [NotifyParentProperty(true)]
346 [PersistenceMode(PersistenceMode.InnerProperty)]
347 [WebSysDescription ("")]
348 [WebCategory ("Style")]
349 public TableItemStyle SelectedDayStyle {
351 if (selectedDayStyle == null) {
352 selectedDayStyle = new TableItemStyle ();
353 if (IsTrackingViewState)
354 selectedDayStyle.TrackViewState ();
357 return selectedDayStyle;
364 [DefaultValue(CalendarSelectionMode.Day)]
365 [WebSysDescription ("")]
366 [WebCategory ("Behavior")]
367 public CalendarSelectionMode SelectionMode {
369 return (CalendarSelectionMode) ViewState.GetInt ("SelectionMode", (int) CalendarSelectionMode.Day);
373 if (value != CalendarSelectionMode.Day && value != CalendarSelectionMode.DayWeek &&
374 value != CalendarSelectionMode.DayWeekMonth && value != CalendarSelectionMode.None) {
375 throw new ArgumentOutOfRangeException ("The specified selection mode is not one of the CalendarSelectionMode values.");
377 ViewState ["SelectionMode"] = value;
384 [DefaultValue(">>")]
388 [WebSysDescription ("")]
389 [WebCategory ("Appearance")]
390 public string SelectMonthText {
392 return ViewState.GetString ("SelectMonthText", ">>");
396 ViewState ["SelectMonthText"] = value;
400 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
401 [NotifyParentProperty(true)]
402 [PersistenceMode(PersistenceMode.InnerProperty)]
403 [WebSysDescription ("")]
404 [WebCategory ("Style")]
405 public TableItemStyle SelectorStyle {
407 if (selectorStyle == null) {
408 selectorStyle = new TableItemStyle ();
409 if (IsTrackingViewState)
410 selectorStyle.TrackViewState ();
413 return selectorStyle;
420 [DefaultValue(">")]
424 [WebSysDescription ("")]
425 [WebCategory ("Appearance")]
426 public string SelectWeekText {
428 return ViewState.GetString ("SelectWeekText", ">");
432 ViewState ["SelectWeekText"] = value;
440 [WebSysDescription ("")]
441 [WebCategory ("Appearance")]
442 public bool ShowDayHeader {
444 return ViewState.GetBool ("ShowDayHeader", true);
448 ViewState ["ShowDayHeader"] = value;
455 [DefaultValue(false)]
456 [WebSysDescription ("")]
457 [WebCategory ("Appearance")]
458 public bool ShowGridLines {
460 return ViewState.GetBool ("ShowGridLines", false);
464 ViewState ["ShowGridLines"] = value;
472 [WebSysDescription ("")]
473 [WebCategory ("Appearance")]
474 public bool ShowNextPrevMonth {
476 return ViewState.GetBool ("ShowNextPrevMonth", true);
480 ViewState ["ShowNextPrevMonth"] = value;
488 [WebSysDescription ("")]
489 [WebCategory ("Appearance")]
490 public bool ShowTitle {
492 return ViewState.GetBool ("ShowTitle", true);
496 ViewState ["ShowTitle"] = value;
503 [DefaultValue(TitleFormat.MonthYear)]
504 [WebSysDescription ("")]
505 [WebCategory ("Appearance")]
506 public TitleFormat TitleFormat {
508 return (TitleFormat) ViewState.GetInt ("TitleFormat", (int) TitleFormat.MonthYear);
512 if (value != TitleFormat.Month && value != TitleFormat.MonthYear) {
513 throw new ArgumentOutOfRangeException ("The specified title format is not one of the TitleFormat values.");
516 ViewState ["TitleFormat"] = value;
520 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
521 [NotifyParentProperty(true)]
522 [PersistenceMode(PersistenceMode.InnerProperty)]
523 [WebSysDescription ("")]
524 [WebCategory ("Style")]
525 public TableItemStyle TitleStyle {
527 if (titleStyle == null) {
528 titleStyle = new TableItemStyle ();
529 if (IsTrackingViewState)
530 titleStyle.TrackViewState ();
538 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
539 [NotifyParentProperty(true)]
540 [PersistenceMode(PersistenceMode.InnerProperty)]
541 [WebSysDescription ("")]
542 [WebCategory ("Style")]
543 public TableItemStyle TodayDayStyle {
545 if (todayDayStyle == null) {
546 todayDayStyle = new TableItemStyle ();
547 if (IsTrackingViewState)
548 todayDayStyle.TrackViewState ();
551 return todayDayStyle;
559 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
560 [WebSysDescription ("")]
561 [WebCategory ("Style")]
562 public DateTime TodaysDate {
564 object obj = ViewState ["TodaysDate"];
567 return (DateTime) obj;
569 return DateTime.Today;
573 ViewState ["TodaysDate"] = value.Date;
578 [DefaultValue (true)]
579 [WebSysDescription ("")]
580 [WebCategoryAttribute ("Accessibility")]
581 public virtual bool UseAccessibleHeader
584 return ViewState.GetBool ("UseAccessibleHeader", true);
587 ViewState ["UseAccessibleHeader"] = value;
593 [DefaultValue("1/1/0001 12:00:00 AM")]
594 [WebSysDescription ("")]
595 [WebCategory ("Style")]
596 public DateTime VisibleDate {
598 object obj = ViewState ["VisibleDate"];
601 return (DateTime) obj;
603 return DateTime.MinValue;
607 ViewState ["VisibleDate"] = value.Date;
611 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
612 [NotifyParentProperty(true)]
613 [PersistenceMode(PersistenceMode.InnerProperty)]
614 [WebSysDescription ("")]
615 [WebCategory ("Style")]
616 public TableItemStyle WeekendDayStyle {
618 if (weekendDayStyle == null) {
619 weekendDayStyle = new TableItemStyle ();
620 if (IsTrackingViewState)
621 weekendDayStyle.TrackViewState ();
624 return weekendDayStyle;
629 // Private properties
630 private DateTime DisplayDate {
632 DateTime dateTime = VisibleDate;
633 if (dateTime == DateTime.MinValue) // If visibledate is still the default value
634 dateTime = TodaysDate;
640 private DayOfWeek DisplayFirstDayOfWeek {
642 if (FirstDayOfWeek != FirstDayOfWeek.Default)
643 return (DayOfWeek) FirstDayOfWeek;
645 return (DayOfWeek) dateInfo.FirstDayOfWeek;
649 protected override ControlCollection CreateControlCollection ()
651 return base.CreateControlCollection ();
654 protected bool HasWeekSelectors (CalendarSelectionMode selectionMode)
656 if (selectionMode == CalendarSelectionMode.DayWeek || selectionMode == CalendarSelectionMode.DayWeekMonth)
663 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
665 RaisePostBackEvent (eventArgument);
668 protected virtual void RaisePostBackEvent (string arg)
670 void IPostBackEventHandler.RaisePostBackEvent (string arg)
676 if (arg[0] == 'V') { // Goes to Next or Previous month
677 DateTime prev = VisibleDate;
678 int days = Int32.Parse (arg.Substring (1));
679 DateTime dt = GetGlobalCalendar().AddDays (dateZenith, days);
681 OnVisibleMonthChanged (VisibleDate, prev);
685 if (arg[0] == 'R') { // Selects a range of dates
686 string num, date, days;
687 num = arg.Substring (1);
688 days = num.Substring (num.Length - 2, 2);
689 date = num.Substring (0, num.Length - 2);
690 DateTime d = GetGlobalCalendar().AddDays (dateZenith, Int32.Parse (date));
691 SelectedDates.SelectRange (d, d.AddDays (Int32.Parse (days)));
692 OnSelectionChanged ();
696 // Selects a single day
697 int daysFromZenith = Int32.Parse (arg);
698 DateTime day = GetGlobalCalendar().AddDays (dateZenith, daysFromZenith);
699 SelectedDates.SelectRange (day, day);
700 OnSelectionChanged ();
703 protected override void LoadViewState (object savedState)
705 object [] states = (object []) savedState;
707 if (states [0] != null)
708 base.LoadViewState (states [0]);
710 if (states [1] != null)
711 DayHeaderStyle.LoadViewState (states [1]);
713 if (states [2] != null)
714 DayStyle.LoadViewState (states [2]);
716 if (states [3] != null)
717 NextPrevStyle.LoadViewState (states [3]);
719 if (states [4] != null)
720 OtherMonthDayStyle.LoadViewState (states [4]);
722 if (states [5] != null)
723 SelectedDayStyle.LoadViewState (states [5]);
725 if (states [6] != null)
726 TitleStyle.LoadViewState (states [6]);
728 if (states [7] != null)
729 TodayDayStyle.LoadViewState (states [7]);
731 if (states [8] != null)
732 SelectorStyle.LoadViewState (states [8]);
734 if (states [9] != null)
735 WeekendDayStyle.LoadViewState (states [9]);
737 ArrayList array = (ArrayList) ViewState ["SelectedDates"];
740 selectedDatesCollection = new SelectedDatesCollection (dateList);
744 protected virtual void OnDayRender (TableCell cell, CalendarDay day)
746 DayRenderEventHandler eh = (DayRenderEventHandler) (Events [DayRenderEvent]);
748 eh (this, new DayRenderEventArgs (cell, day));
756 override void OnPreRender (EventArgs e)
758 base.OnPreRender (e);
761 protected virtual void OnSelectionChanged ()
763 EventHandler eh = (EventHandler) (Events [SelectionChangedEvent]);
765 eh (this, EventArgs.Empty);
768 protected virtual void OnVisibleMonthChanged (DateTime newDate, DateTime previousDate)
770 MonthChangedEventHandler eh = (MonthChangedEventHandler) (Events [VisibleMonthChangedEvent]);
772 eh (this, new MonthChangedEventArgs (newDate, previousDate));
780 override void Render (HtmlTextWriter writer)
782 Table table = new Table ();
783 table.CellSpacing = CellSpacing;
784 table.CellPadding = CellPadding;
785 if (ControlStyleCreated)
786 table.ControlStyle.CopyFrom (ControlStyle);
787 table.CopyBaseAttributes (this);
791 table.GridLines = GridLines.Both;
793 table.RenderBeginTag (writer);
797 WriteCaption (writer);
804 WriteDayHeader (writer);
808 table.RenderEndTag (writer);
811 protected override object SaveViewState ()
813 object [] states = new object [10];
815 if (dayHeaderStyle != null)
816 states [1] = dayHeaderStyle.SaveViewState ();
818 if (dayStyle != null)
819 states [2] = dayStyle.SaveViewState ();
821 if (nextPrevStyle != null)
822 states [3] = nextPrevStyle.SaveViewState ();
824 if (otherMonthDayStyle != null)
825 states [4] = otherMonthDayStyle.SaveViewState ();
827 if (selectedDayStyle != null)
828 states [5] = selectedDayStyle.SaveViewState ();
830 if (titleStyle != null)
831 states [6] = titleStyle.SaveViewState ();
833 if (todayDayStyle != null)
834 states [7] =todayDayStyle.SaveViewState ();
836 if (selectorStyle != null)
837 states [8] = selectorStyle.SaveViewState ();
839 if (weekendDayStyle != null)
840 states [9] = weekendDayStyle.SaveViewState ();
842 if (SelectedDates.Count > 0) {
843 ViewState ["SelectedDates"] = dateList;
846 states [0] = base.SaveViewState ();
848 for (int i = 0; i < states.Length; i++) {
849 if (states [i] != null) {
857 protected override void TrackViewState ()
859 base.TrackViewState ();
861 if (dayHeaderStyle != null)
862 dayHeaderStyle.TrackViewState ();
864 if (dayStyle != null)
865 dayStyle.TrackViewState ();
867 if (nextPrevStyle != null)
868 nextPrevStyle.TrackViewState ();
870 if (otherMonthDayStyle != null)
871 otherMonthDayStyle.TrackViewState ();
873 if (selectedDayStyle != null)
874 selectedDayStyle.TrackViewState ();
876 if (titleStyle != null)
877 titleStyle.TrackViewState ();
879 if (todayDayStyle != null)
880 todayDayStyle.TrackViewState ();
882 if (selectorStyle != null)
883 selectorStyle.TrackViewState ();
885 if (weekendDayStyle != null)
886 weekendDayStyle.TrackViewState ();
892 private void WriteDayHeader (HtmlTextWriter writer)
896 i = first = (int) (DisplayFirstDayOfWeek);
900 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
902 if (SelectionMode == CalendarSelectionMode.DayWeek) {
903 cell = new TableCell();
904 cell.HorizontalAlign = HorizontalAlign.Center;
905 cell.ApplyStyle (DayHeaderStyle);
908 cell.RenderBeginTag (writer);
909 cell.RenderEndTag (writer);
911 if (SelectionMode == CalendarSelectionMode.DayWeekMonth) {
912 TableCell selector = new TableCell ();
913 selector.ApplyStyle (SelectorStyle);
914 selector.HorizontalAlign = HorizontalAlign.Center;
916 DateTime date = new DateTime (DisplayDate.Year, DisplayDate.Month, 1); // first date
917 int days = DateTime.DaysInMonth (DisplayDate.Year, DisplayDate.Month);
919 selector.RenderBeginTag (writer);
920 writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + days, SelectMonthText, DayHeaderStyle.ForeColor, true));
921 selector.RenderEndTag (writer);
926 DayOfWeek dayOfWeek = (DayOfWeek) i;
927 dayName = dateInfo.GetDayName (dayOfWeek);
930 if (UseAccessibleHeader) {
931 writer.AddAttribute (HtmlTextWriterAttribute.Abbr, dayName);
932 writer.AddAttribute (HtmlTextWriterAttribute.Scope, "col");
933 cell = new TableHeaderCell();
937 cell = new TableCell();
939 cell.HorizontalAlign = HorizontalAlign.Center;
940 cell.ApplyStyle (DayHeaderStyle);
942 cell.RenderBeginTag (writer);
944 switch (DayNameFormat) {
945 case DayNameFormat.FirstLetter:
946 dayName = dayName.Substring (0, 1);
948 case DayNameFormat.FirstTwoLetters:
949 dayName = dayName.Substring (0, 2);
951 case DayNameFormat.Full:
953 case DayNameFormat.Short:
955 dayName = dateInfo.GetAbbreviatedDayName (dayOfWeek);
959 writer.Write (dayName);
960 cell.RenderEndTag (writer);
962 if (i >= daysInAWeek - 1) {
972 writer.RenderEndTag ();
975 private void WriteDay (DateTime date, HtmlTextWriter writer)
977 Style style = new Style ();
978 TableCell cell = new TableCell ();
980 CalendarDay day = new CalendarDay (date,
981 IsWeekEnd (date.DayOfWeek),
982 date == TodaysDate, SelectedDates.Contains (date),
983 GetGlobalCalendar ().GetMonth (DisplayDate) != GetGlobalCalendar ().GetMonth (date),
984 date.Day.ToString ());
986 day.IsSelectable = SelectionMode != CalendarSelectionMode.None;
987 cell.HorizontalAlign = HorizontalAlign.Center;
988 cell.Width = Unit.Percentage (GetCellWidth ());
990 LiteralControl lit = new LiteralControl (day.DayNumberText);
991 cell.Controls.Add (lit);
993 OnDayRender (cell, day);
995 if (dayStyle != null && !dayStyle.IsEmpty) {
996 style.CopyFrom (dayStyle);
999 if (day.IsWeekend && weekendDayStyle != null && !weekendDayStyle.IsEmpty) {
1000 style.CopyFrom (weekendDayStyle);
1003 if (day.IsToday && todayDayStyle != null && !todayDayStyle.IsEmpty) {
1004 style.CopyFrom (todayDayStyle);
1007 if (day.IsOtherMonth && otherMonthDayStyle != null && !otherMonthDayStyle.IsEmpty) {
1008 style.CopyFrom (otherMonthDayStyle);
1011 if (day.IsSelected) {
1012 style.BackColor = Color.Silver;
1013 style.ForeColor = Color.White;
1014 if (selectedDayStyle != null && !selectedDayStyle.IsEmpty) {
1015 style.CopyFrom (selectedDayStyle);
1019 cell.ApplyStyle (style);
1021 lit.Text = BuildLink (GetDaysFromZenith (date).ToString (), day.DayNumberText,
1022 cell.ForeColor, day.IsSelectable);
1024 cell.RenderControl (writer);
1027 private void WriteDays (HtmlTextWriter writer)
1029 DateTime date = new DateTime (DisplayDate.Year, DisplayDate.Month, 1); // first date
1031 TableCell selectorCell = null;
1034 // Goes backwards until we find the date of that is begining of the week
1035 for (n = 0; n < daysInAWeek; n++) {
1036 if (date.DayOfWeek == DisplayFirstDayOfWeek)
1039 date = GetGlobalCalendar().AddDays (date, -1);
1041 /* if the start date is the first day of the week, we need to shift backward one more week */
1043 date = GetGlobalCalendar().AddDays (date, -1 * daysInAWeek);
1045 lastDate = GetGlobalCalendar().AddDays (date, 6 * daysInAWeek); // Always six weeks per months
1048 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1050 if (HasWeekSelectors (SelectionMode)) { // Week selector
1051 if (selectorCell == null) {
1052 selectorCell = new TableCell ();
1053 selectorCell.ApplyStyle (SelectorStyle);
1054 selectorCell.HorizontalAlign = HorizontalAlign.Center;
1055 selectorCell.Width = Unit.Percentage (GetCellWidth ());
1058 selectorCell.RenderBeginTag (writer);
1059 writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + "07", SelectWeekText, selectorCell.ForeColor, true));
1060 selectorCell.RenderEndTag (writer);
1063 for (int i = 0; i < daysInAWeek; i++) {
1064 WriteDay (date, writer);
1065 date = GetGlobalCalendar().AddDays (date, 1);
1068 writer.RenderEndTag ();
1069 if (date >= lastDate)
1074 private string BuildLink (string arg, string text, Color foreColor, bool hasLink)
1076 string str = string.Empty;
1078 hasLink = (Page != null && hasLink == true) ? true : false;
1082 str += Page.ClientScript.GetPostBackClientHyperlink (this, arg);
1086 if (!foreColor.IsEmpty) {
1089 if (ForeColor.IsEmpty)
1095 str += " style=color:" + ColorTranslator.ToHtml (clr);
1106 private int GetDaysFromZenith (DateTime date)
1108 TimeSpan span = date.Subtract (dateZenith);
1113 void WriteCaption (HtmlTextWriter writer)
1115 if (CaptionAlign != TableCaptionAlign.NotSet)
1116 writer.AddAttribute (HtmlTextWriterAttribute.Align, CaptionAlign.ToString (CultureInfo.InvariantCulture));
1118 writer.RenderBeginTag (HtmlTextWriterTag.Caption);
1119 writer.Write (Caption);
1120 writer.RenderEndTag ();
1124 private void WriteTitle (HtmlTextWriter writer)
1126 TableCell cellNextPrev = null;
1127 TableCell titleCell = new TableCell ();
1128 Table tableTitle = new Table ();
1130 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1132 titleCell.ColumnSpan = HasWeekSelectors (SelectionMode) ? 8 : 7;
1134 if (titleStyle != null && !titleStyle.IsEmpty && !titleStyle.BackColor.IsEmpty) {
1135 titleCell.BackColor = titleStyle.BackColor;
1137 titleCell.BackColor = Color.Silver;
1140 titleCell.RenderBeginTag (writer);
1143 tableTitle.Width = Unit.Percentage (100);
1144 if (titleStyle != null && !titleStyle.IsEmpty) {
1145 tableTitle.ApplyStyle (titleStyle);
1148 tableTitle.RenderBeginTag (writer);
1149 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1151 if (ShowNextPrevMonth) { // Previous Table Data
1152 cellNextPrev = new TableCell ();
1153 cellNextPrev.ApplyStyle (nextPrevStyle);
1154 cellNextPrev.Width = Unit.Percentage (15);
1156 DateTime date = GetGlobalCalendar().AddMonths (DisplayDate, - 1);
1157 date = GetGlobalCalendar().AddDays (date, -DisplayDate.Day + 1);
1158 cellNextPrev.RenderBeginTag (writer);
1159 writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, false), cellNextPrev.ForeColor, true));
1160 cellNextPrev.RenderEndTag (writer);
1163 // Current Month Table Data
1166 TableCell cellMonth = new TableCell ();
1167 cellMonth.Width = Unit.Percentage (70);
1168 cellMonth.HorizontalAlign = HorizontalAlign.Center;
1170 cellMonth.RenderBeginTag (writer);
1172 str = dateInfo.GetMonthName (GetGlobalCalendar ().GetMonth (DisplayDate));
1174 if (TitleFormat == TitleFormat.MonthYear)
1175 str += " " + (DisplayDate.Year.ToString ());
1178 cellMonth.RenderEndTag (writer);
1181 if (ShowNextPrevMonth) { // Next Table Data
1182 DateTime date = GetGlobalCalendar().AddMonths (DisplayDate, + 1);
1183 date = GetGlobalCalendar().AddDays (date, -DisplayDate.Day + 1);
1185 cellNextPrev.HorizontalAlign = HorizontalAlign.Right;
1186 cellNextPrev.RenderBeginTag (writer);
1187 writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, true), cellNextPrev.ForeColor, true));
1188 cellNextPrev.RenderEndTag (writer);
1191 writer.RenderEndTag ();
1192 tableTitle.RenderEndTag (writer);
1193 titleCell.RenderEndTag (writer);
1194 writer.RenderEndTag (); //tr
1199 private string GetNextPrevFormatText (DateTime date, bool next)
1202 switch (NextPrevFormat) {
1203 case NextPrevFormat.FullMonth:
1204 text = dateInfo.GetMonthName (GetGlobalCalendar ().GetMonth (date));
1206 case NextPrevFormat.ShortMonth:
1207 text = dateInfo.GetAbbreviatedMonthName (GetGlobalCalendar ().GetMonth (date));
1209 case NextPrevFormat.CustomText:
1211 text = ((next) ? NextMonthText : PrevMonthText);
1218 private bool IsWeekEnd (DayOfWeek day)
1220 return (day == DayOfWeek.Saturday || day == DayOfWeek.Sunday);
1223 private double GetCellWidth ()
1225 return HasWeekSelectors (SelectionMode) ? 100/8 : 100/7;
1228 private System.Globalization.Calendar GetGlobalCalendar ()
1230 return DateTimeFormatInfo.CurrentInfo.Calendar;
1233 [WebSysDescription ("")]
1234 [WebCategory ("Action")]
1235 public event DayRenderEventHandler DayRender {
1237 Events.AddHandler (DayRenderEvent, value);
1240 Events.RemoveHandler (DayRenderEvent, value);
1244 [WebSysDescription ("")]
1245 [WebCategory ("Action")]
1246 public event EventHandler SelectionChanged {
1248 Events.AddHandler (SelectionChangedEvent, value);
1251 Events.RemoveHandler (SelectionChangedEvent, value);
1255 [WebSysDescription ("")]
1256 [WebCategory ("Action")]
1257 public event MonthChangedEventHandler VisibleMonthChanged {
1259 Events.AddHandler (VisibleMonthChangedEvent, value);
1262 Events.RemoveHandler (VisibleMonthChangedEvent, value);